https://codeforces.com/contest/1102/problem/A
题意:给定一个数n,将1-n分成两组,使得两组数的差值最小,输出最小差值。
思路:根据推理发现,随着n的增大,是有规律出现的,跟4的倍数有关系。
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
#define ll long long
int main()
{
ll n;
while(scanf("%lld",&n)!=EOF)
{
if(n%4==0)
cout<<0<<endl;
else if(n%4==1)
cout<<1<<endl;
else if(n%4==2)
cout<<1<<endl;
else if(n%4==3)
cout<<0<<endl;
}
return 0;
}
https://codeforces.com/contest/1102/problem/B
题意:给定n个数和k种颜色,要求这n个数字中相等的应该用不同的颜色涂色,并且这k种颜色都应该使用,所以只需要两次排序,第一次将这n个数从此小到大排序,然后将这k个数分别取余放上,之后再将这n个数,按照输入的顺序排序在输出颜色的排布。
#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define inf 0x3f3f3f3f
const int maxn = 400+100;
struct node
{
int x,pos,ks;
}pp[100005];
bool cmp2(node a,node b)
{
return a.x<b.x;
}
bool cmp1(node a,node b)
{
return a.pos<b.pos;
}
int main()
{
int n,k;
int vis[100005];
while(scanf("%d %d",&n,&k)!=EOF)
{
memset(vis,0,sizeof(vis));
int maxx=-inf;
for(int i=0;i<n;i++)
{
scanf("%d",&pp[i].x);
vis[pp[i].x]++;
maxx=max(maxx,pp[i].x);
pp[i].pos=i;
}
sort(pp,pp+n,cmp2);
/* for(int i=0;i<n;i++)
{
printf("%d ",pp[i].x);
}*/
if(n<k)
{
printf("NO\n");
return 0;
}
for(int i=1;i<=maxx;i++)
{
if(vis[i]>k)
{
printf("NO\n");
return 0;
}
}
int cur=1;
for(int i=0;i<n;i++)
{
// printf("%d ",cur);
if(cur%k==0)
pp[i].ks=k;
else
pp[i].ks=cur%k;
cur++;
}
sort(pp,pp+n,cmp1);
/* for(int i=0;i<n;i++)
{
printf("%d ",pp[i].pos);
}*/
printf("YES\n");
for(int i=0;i<n;i++)
{
if(i==0)
printf("%d",pp[i].ks);
else
printf(" %d",pp[i].ks);
}
printf("\n");
}
return 0;
}
https://codeforces.com/contest/1102/problem/C
题意:有n扇门,每扇门有一定的防御值,其中一个人有x的攻击力,另一个人有y的修复力,请问,x最多可以破坏几扇门。
思路:如果说,x的破坏力大于y那么他将破坏所有的门,但是如果,x<y 那么寻找防御值小于x的破坏,然后就能推出公式
#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define inf 0x3f3f3f3f
const int maxn = 400+100;
int main()
{
int n,x,y;
while(scanf("%d %d %d",&n,&x,&y)!=EOF)
{
int ans=0;
for(int i=0;i<n;i++)
{
int cur;
scanf("%d",&cur);
if(cur<=x)
ans++;
}
if(x>y)
printf("%d\n",n);
else
{
ans++;
ans/=2;
printf("%d\n",ans);
}
}
return 0;
}
https://codeforces.com/contest/1102/problem/D
题意:给定n个数由012三个数字组成,现在要求用最少的次数,使这三种数字的数量相等,而且必须满足字典序最小。
思路:先统计一下012分别出现的个数,然后从前往后,从后往前分别扫一遍
#include<bits/stdc++.h>
#include<iostream>
#define ll long long
using namespace std;
int main()
{
int n;
string ch;
int vis[10];
while(scanf("%d",&n)!=EOF)
{
cin>>ch;
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
{
vis[ch[i]-'0']++;
}
for(int i=0;i<n;i++)
{
if(vis[0]<n/3&&vis[ch[i]-'0']>n/3&&ch[i]!='0')vis[0]++,vis[ch[i]-'0']--,ch[i]='0';
if(vis[1]<n/3&&vis[ch[i]-'0']>n/3&&ch[i]=='2')vis[1]++,vis[2]--,ch[i]='1';
}
for(int i=n-1;i>=0;i--)
{
if(vis[2]<n/3&&vis[ch[i]-'0']>n/3&&ch[i]!='2')vis[2]++,vis[ch[i]-'0']--,ch[i]='2';
if(vis[1]<n/3&&vis[ch[i]-'0']>n/3&&ch[i]=='0')vis[1]++,vis[ch[i]-'0']--,ch[i]='1';
}
cout<<ch<<endl;
}
return 0;
}