A | B | C | D | E1 | E2 |
---|---|---|---|---|---|
√ | √ | √ | √ |
( √:做出; ●:尝试未做出; ○:已补题 )
题目地址:https://codeforces.com/contest/1393
题意:签到题
思路:
代码:
#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include
#include
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
int x=0,flag=1; char c=getchar();
while((c>'9' || c<'0') && c!='-') c=getchar();
if(c=='-') flag=0,c=getchar();
while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
return flag?x:-x;
}
int main()
{
int t=read();
while(t--)
{
int n=read();
cout<<n/2+1<<endl;
}
return 0;
}
题意:要求维护若干条边,每次可以增加一条某个长度的边,或者删除一条某个长度的边,你需要在每次操作结束后回答,这些边是否可以组成一个正方形加一个长方形。
思路:动态维护两个数 n2 和 n4(分别表示可以组成两条相同的边的对数,以及可以组成四条相同的边的对数),因为只需要一个正方形一个长方形,所以只需要在 8 以内更改这两个数就行了。最后存在的条件是 n4>=2 || (n4>0 && n2>=2)
。
代码:
#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include
#include
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
int x=0,flag=1; char c=getchar();
while((c>'9' || c<'0') && c!='-') c=getchar();
if(c=='-') flag=0,c=getchar();
while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
return flag?x:-x;
}
const int maxn=1e5+5;
int a[maxn],n2=0,n4=0;
char s[10];
void add(int x)
{
a[x]++;
if(a[x]==2) n2++;
else if(a[x]==4) n2--,n4++;
else if(a[x]==6) n2++;
else if(a[x]==8) n2--,n4++;
}
void del(int x)
{
a[x]--;
if(a[x]==1) n2--;
else if(a[x]==3) n2++,n4--;
else if(a[x]==5) n2--;
else if(a[x]==7) n2++,n4--;
}
int main()
{
int n=read();
REP(i,1,n)
{
int x=read();
add(x);
}
int q=read();
while(q--)
{
scanf("%s",s);
int x=read();
if(s[0]=='+') add(x);
else if(s[0]=='-') del(x);
puts((n4>=2 || (n4==1 && n2>=2))?"YES":"NO");
}
return 0;
}
题意:有很多饼干,要把他们排成一排,把两两相同的饼干之间的间距拿出来,取这所有间距之间的最小值,目标是要使这个最小值最大,问这个最小值最大是多少。
思路:一开始一直在想二分,后来想着想着发现,我们只需要考虑最多的饼干就行了,因为少的那些完全可以在充分满足 最多的饼干之后,以同样的间距插进去,因为它们不需要最多的那么多位置,所以一定可行。还需要考虑最多的饼干有多少种,然后把它们平均分进去,算一下间距就行了。
算间距的方法大概就是,假设有 tot 种最多的饼干,最多的饼干每种有 m 个,那么其中的一个的第一个就放在第一个位置,最后一个应该放在第 n-tot+1 个位置,然后中间平均放,然后计算间距即可。
代码:
#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include
#include
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
int x=0,flag=1; char c=getchar();
while((c>'9' || c<'0') && c!='-') c=getchar();
if(c=='-') flag=0,c=getchar();
while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
return flag?x:-x;
}
const int maxn=1e5+5;
int num[maxn];
int main()
{
int T=read();
while(T--)
{
int n=read();
REP(i,1,n) num[i]=0;
REP(i,1,n)
{
int x=read();
num[x]++;
}
int m=0;
REP(i,1,n) m=max(m,num[i]);
int tot=0;
REP(i,1,n) tot+=num[i]==m;
printf("%d\n",(n-m-tot+1)/(m-1));
}
return 0;
}
题意:给你一块布,布上面每个方块有一个颜色,你要从布上面剪下一个呈 45° 的正方形,并且要求这个正方形的颜色只有一种,问有多少种剪法。以下这三种都是合法的 45° 的正方形:
(图片截图于 https://codeforces.com/contest/1393/problem/D)
思路:设 f(i, j) 表示以 (i, j) 作为底端的点,往上能延伸的正方形的最大边长,那么对于每个 f(i, j) ,假设它和它 上面、左上、右上、上上 之间有不一样的颜色,那么 f(i, j)=1;如果全都一样,那么就取上面四个的 f 中的最小值 minx,那么 f(i, j)=minx+1 。最后计算 f 的和就是答案。
代码:
#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include
#include
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
int x=0,flag=1; char c=getchar();
while((c>'9' || c<'0') && c!='-') c=getchar();
if(c=='-') flag=0,c=getchar();
while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
return flag?x:-x;
}
const int maxn=2005;
int f[maxn][maxn];
char s[maxn][maxn];
int main()
{
int n=read(),m=read();
REP(i,1,n) scanf("%s",s[i]+1);
REP(i,1,2) REP(j,1,m) f[i][j]=1;
REP(i,3,n) REP(j,1,m)
{
if(j==1 || j==m) {f[i][j]=1; continue;}
if(s[i][j]!=s[i-1][j-1] || s[i][j]!=s[i-1][j] ||s[i][j]!=s[i-1][j+1] || s[i][j]!=s[i-2][j])
{
f[i][j]=1;
continue;
}
int x=100000;
x=min(x,f[i-1][j-1]);
x=min(x,f[i-1][j]);
x=min(x,f[i-1][j+1]);
x=min(x,f[i-2][j]);
f[i][j]=x+1;
}
LL ans=0;
REP(i,1,n) REP(j,1,m) ans+=f[i][j];
cout<<ans;
return 0;
}
题意:
思路:
代码:
题意:
思路:
代码: