题目来源:http://acm.fzu.edu.cn/problem.php?pid=1534
Problem 1534 阿甘的珠宝
Accept: 95 Submit: 293
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
阿甘向来好运连连,他在好心人的带领下发现了基督山伯爵的宝藏。珠宝~~满眼都是珠宝!!!但是守护的神灵对阿甘提出了苛刻的要求,“你要珠宝,必须赢了我再说。”
阿甘要和守护神灵玩这样一个游戏,规则如下:
- 阿甘眼前有n堆珠宝,n≤10000;
- 每堆珠宝有mi个,0≤mi≤2^31-1;
- 每人每轮可以拿走一堆珠宝中2^i个,比如1,2,4,8…..(不能不拿);
- 阿甘先拿。
- 由守护申领决定取到最后一个赢or输。
守护神拥有千年的生命,无比智慧,阿甘是否能赢呢?
Input
多组数据输入。每组数据包括:
一个整数n,接下来n行每行一个整数,表示mi。
第n+1行有一个数0或者1,表示取到最后一个赢或者输。
Output
阿甘能赢则输出一行yes,否则输出no。
Sample Input
2
5
4
0
Sample Output
yes
分析:
1:每堆珠宝有mi个,0≤mi≤2^31-1;, 我们知道 这个大数据是没办法用数组存的,否则会超内存。 我们需要计算sg[mi] , 由于f[]是很规律的 步长, 我们 试着用文件的操作 找出这样的规律。
2:文件操作:
FILE fp;
fp = fopen("test.txt","w");
fclose(fp);
3:我们找出 sg[x] = x%3; 对的, 就是如此简单。
4:分两种情况:
当最后取完石子的 人 为赢。 则 异或值为0, 表示P_position. (先手必输态)
当最后取完石子的人 为输。 则 T2 和 S0 ,表示 P_position(先手必输态)
T2 表示 异或值=0 && 充裕堆>=2 充裕堆 表示 堆中的 石子 不止一个(注意 堆中的石子可以为0,因此还wa)
S0 表示 异或值!=0 && 充裕堆==0
代码如下:
#include<iostream> #include<stdlib.h> #include<stdio.h> #include<math.h> #include<string.h> #include<string> #include<queue> #include<algorithm> #include<map> #include<set> #define Inf 0x7fffffff // 0x 是数字0,而不是字母o #define N 10001 using namespace std; typedef long long LL; int main(){ int n,unalone,ans,flag,temp,zero; while(cin>>n) { unalone=0,ans=0,zero=0; for(int i=0;i<n;i++) { cin>>temp; if(temp>1) unalone++; if(temp==0) zero++; ans^=(temp%3); } cin>>flag; if(flag ==0) { if(ans) puts("yes"); else puts("no"); } else { if(zero == n) {puts("yes");continue;} if((ans==0 && unalone>=2) || (ans && unalone==0)) puts("no"); else puts("yes"); } } return 0; }