刚刚结束比赛,还没hack,要是被hack了再说。(被hack了b,从260掉到了496,人生第一次打这么好的比赛就被hack了,难受)
A Rainbow Dash, Fluttershy and Chess Coloring
传送门:https://codeforces.com/contest/1393/problem/A
第一题,两个人画图,给出n*n的空白正方形,只能贴边画或者贴已经画过的画,并且必须斜着对应。
没这么弄懂题意。但是看着应该是一个找规律,比如5的问题,把边贴两遍就变成3的问题。所以找个规律就行了。
题意真的坑,读了十分钟读不懂就莽了。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void rlmn()
{
int n;
scanf("%d",&n);
int ans=n/2;
printf("%d\n",ans+1);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)rlmn();
return 0;
}
B Applejack and Storages
传送门 https://codeforces.com/contest/1393/problem/B
被hack了。原因是题目没有说ai<n,我默认了这个条件(估计不少人都默认了这个条件,思维定势了,死了一大片)
题意:小马们想做一个方形的和矩形的马厩,每个马厩需要四块木板。现在家具场有一些木板,每次回增加或者减少一个木板。问每次增加或者减少的时候能不能符合要求早出一个方形和一个矩形的马厩。
方法:维护一个fangnum和一个junum,然后当木板增加减少到了边界的时候,就进行一次判断,更新fangnum和junum的数量,最后通过fangnum和junum判断是否能够成功搭建。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100005];
void rlmn()
{
int n;
scanf("%d",&n);
int tmp;
int maxa=0;
for (int i=0;i<n;i++)
{
scanf("%d",&tmp);
if (tmp>maxa) maxa=tmp;
a[tmp]++;
}
int zhengnum=0;
int junum=0;
for (int i=0;i<=maxa;i++)
{
zhengnum+=a[i]/4;
junum+=a[i]/2;
}
int m;
scanf("%d",&m);
char t,t1;
while (m--)
{
getchar();
scanf("%c%c%d",&t,&t1,&tmp);
if (t=='+')
{
a[tmp]++;
if (a[tmp]%4==0)
{
zhengnum++;
junum++;
}
if (a[tmp]%4==2)
{
junum++;
}
}
else
{
a[tmp]--;
if (a[tmp]%4==3)
{
zhengnum--;
junum--;
}
if (a[tmp]%4==1)
{
junum--;
}
}
if (zhengnum>=2||(zhengnum>=1&&(junum-2*zhengnum)>=2))
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
}
int main()
{
int T;
T=1;
while(T--)rlmn();
return 0;
}
C Pinkie Pie Eats Patty-cakes
传送门:https://codeforces.com/contest/1393/problem/C
题意:给你一些数字,让你把这些数字尽可能的分散开来,问两个相同数字的最小间距的最大值是多少。
方法:维护一个tmp,代表相同数的数量。再维护一个num,代表最大数量的数量。然后按ans=(n-num)/(tmp-1)-1计算即可。原因是为了把数尽量分开就需要分堆,同是最大数量的数量放在不同的堆,自己画一画就可以画出来。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100005];
int cmp(int x,int y)
{
return x>y;
}
void rlmn()
{
int n;
scanf("%d",&n);
int tmp;
memset(a,0,sizeof(a));
for (int i=0;i<n;i++)
{
scanf("%d",&tmp);
a[tmp]++;
}
sort(a,a+n+1,cmp);
tmp=a[0];
int num=0;
for (int i=0;i<n;i++)
{
if (tmp==a[i])
{
num++;
}
else
break;
}
int ans=(n-num)/(tmp-1)-1;
printf("%d\n",ans);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)rlmn();
return 0;
}
D:Rarity and New Dress
传送门:https://codeforces.com/contest/1393/problem/D
题意:小红有强迫症,她必须要方形的裙子,但是必须是旋转45度的那种方形,并且裙子的颜色必须一样。(这题不难懂,看看图大家都能看懂)
这题和有一题也是codeforces的题目很像,之前做过,也是四个角进行dp,想一想其实很简单。比如左上的那种dp,每次维护一下左边和上面是不是有,然后有的话就取他们俩中值小的那一个再加1.然后重复四个方向即可。当然复杂度似乎是2000*2000*4,可能能到16000000,存在被卡t的可能性。
我写的时候思路有点乱,将就着看。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int dp[4][2005][2005];
char a[2005][2005];
void rlmn()
{
int n,m;
scanf("%d%d",&n,&m);
memset(dp,0,sizeof(dp));
for (int i=0;i<n;i++)
{
scanf("%s",a[i]);
}
//上左
for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
if (i==0||j==0||i==n-1||j==m-1)
{
continue;
}
if (a[i][j]==a[i-1][j]&&a[i][j]==a[i][j-1])
{
dp[0][i][j]=max(1,min(dp[0][i-1][j],dp[0][i][j-1])+1);
}
}
}
//上右
for (int i=0;i<n;i++)
{
for (int j=m-1;j>=0;j--)
{
if (i==0||j==0||i==n-1||j==m-1)
{
continue;
}
if (a[i][j]==a[i-1][j]&&a[i][j]==a[i][j+1])
{
dp[1][i][j]=max(1,min(dp[1][i-1][j],dp[1][i][j+1])+1);
}
}
}
//下左
for (int i=n-1;i>=0;i--)
{
for (int j=0;j<m;j++)
{
if (i==0||j==0||i==n-1||j==m-1)
{
continue;
}
if (a[i][j]==a[i+1][j]&&a[i][j]==a[i][j-1])
{
dp[2][i][j]=max(1,min(dp[2][i+1][j],dp[2][i][j-1])+1);
}
}
}
//下右
for (int i=n-1;i>=0;i--)
{
for (int j=m-1;j>=0;j--)
{
if (i==0||j==0||i==n-1||j==m-1)
{
continue;
}
if (a[i][j]==a[i+1][j]&&a[i][j]==a[i][j+1])
{
dp[3][i][j]=max(1,min(dp[3][i+1][j],dp[3][i][j+1])+1);
}
}
}
/*
for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
printf("%d ",min(min(dp[0][i][j],dp[1][i][j]),min(dp[2][i][j],dp[3][i][j])));
}
printf("\n");
}
*/
int ans=0;
for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
ans++;
ans+=min(min(dp[0][i][j],dp[1][i][j]),min(dp[2][i][j],dp[3][i][j]));
}
}
printf("%d\n",ans);
}
int main()
{
int T;
T=1;
while(T--)rlmn();
return 0;
}