http://codeforces.com/contest/469
A 水题不解释
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
int flag[10004];
int n;
int main()
{
while(~scanf("%d",&n))
{
int x;
memset(flag,0,sizeof(flag));
scanf("%d",&x);
int c;
for(int i=0;i<x;i++)
{
scanf("%d",&c);
flag[c]=1;
}
scanf("%d",&x);
for(int i=0;i<x;i++)
{
scanf("%d",&c);
flag[c]=1;
}
int cnt=1;
for(int i=1;i<=n;i++)
{
if(flag[i]==0)
cnt=0;
}
if(cnt==1)
printf("I become the guy.\n");
else
printf("Oh, my keyboard!\n");
}
return 0;
}
B我采用的方法是:
对于 Z 的时间段,在之内的标记为1,不在之内的标记为零,求前向和,然后枚举X可能移动的位置取合适的点。
有几点值得注意的地方参见代码注释。
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
int p,q,l,r,a[55][2],b[55][2],sum[20005],flag[20005];//数组要开的远大于1000,防止求前和的时候出现数组越界
bool judge(int t)
{
int ans=0;
for(int i=0;i<q;i++)
{
int x=b[i][0]+t;
int y=b[i][1]+t;
if(x==0)//x==0的时候要特殊考虑
ans=sum[y]-sum[x]+flag[0];
else
ans=sum[y]-sum[x-1];
if(ans>0)
return true;
}
return false;
}
int main()
{
while(~scanf("%d%d%d%d",&p,&q,&l,&r))
{
memset(flag,0,sizeof(flag));
memset(sum,0,sizeof(sum));
for(int i=0;i<p;i++)
{
scanf("%d%d",&a[i][0],&a[i][1]);
for(int j=a[i][0];j<=a[i][1];j++)
flag[j]=1;
}
sum[0]=flag[0];
for(int i=1;i<=10002;i++)//不能只仅仅到1000
sum[i]=sum[i-1]+flag[i];
int cnt=0;
for(int i=0;i<q;i++)
scanf("%d%d",&b[i][0],&b[i][1]);
for(int i=l;i<=r;i++)
{
if(judge(i))
{
//printf("(%d)\n",i);
cnt++;
}
}
printf("%d\n",cnt);
}
return 0;
}
C 题:求24点,远没有想的那么复杂,这题就是一道找规律的题,我们可以发现,对于4一下的根本不能实现,4的时候可以4*2*3*1=24;4以后如果是偶数就是:
偶数-偶数-1=1, 偶数+2*1=偶数+2, 最后一个偶数+2换成: 1*24=24;如果是奇数,我们亦可以发现:5*4+3+2-1=24,后面的与是偶数的类似。
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
int n;
int main()
{
while(~scanf("%d",&n))
{
if(n<4)
printf("NO\n");
else
{
printf("YES\n");
if(n%2==0)
{
printf("3 * 2 = 6\n");
printf("6 * 4 = 24\n");
printf("24 * 1 = 24\n");
if(n>4)
{
for(int i=5; i<n-1; i+=2)
{
printf("%d - %d = 1\n",i+1,i);
printf("1 * %d = %d\n",i+2,i+2);
}
printf("%d - %d = 1\n",n,n-1);
printf("24 * 1 = 24\n");
}
}
else
{
printf("5 * 4 = 20\n");
printf("3 + 20 = 23\n");
printf("23 - 1 = 22\n");
printf("22 + 2 = 24\n");
if(n>5)
{
for(int i=6; i<n-1; i+=2)
{
printf("%d - %d = 1\n",i+1,i);
printf("1 * %d = %d\n",i+2,i+2);
}
printf("%d - %d = 1\n",n,n-1);
printf("24 * 1 = 24\n");
}
}
}
}
return 0;
}
D题:我用bfs做的,参考了一下A过的人的想法。
刚开始把所有的数都设为A集合里的,对于那些a-x不在A集合里面的数我们加入队列,定为B集合,如果b-x不在已经给出的序列中,无解。然后判断 a - ( b - x ),如果在 加入队列。。直到队列为空。
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
using namespace std;
map<int,int>mp;
queue<int>q;
int num[100005],a,b,n;
int main()
{
while(~scanf("%d%d%d",&n,&a,&b))
{
for(int i=0; i<n; i++)
{
scanf("%d",&num[i]);
mp[num[i]]=1;
}
while(!q.empty())
q.pop();
for(int i=0; i<n; i++)
if(!mp[a-num[i]])
q.push(num[i]);
int flag=1;
while(!q.empty())
{
int u=q.front();
q.pop();
if(mp[u]>0&&mp[a-u]==0&&mp[b-u]==0)
{
printf("NO\n");
flag=0;
break;
}
mp[u]--;
mp[b-u]--;
int cnt=a-b+u;
if(mp[cnt])
q.push(cnt);
}
if(flag==1)
{
printf("YES\n");
for(int i=0; i<n-1; i++)
{
if(mp[num[i]]==1)
printf("0 ");
else
printf("1 ");
}
if(mp[num[n-1]]==1)
printf("0\n");
else
printf("1\n");
}
}
return 0;
}