hdu5724Chess
2016-07-19 17:06
405 查看
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5724
题意:有个n*20的表格,每行有若干棋子,两个人轮流移动。每次移动棋子只能将这枚棋子移动到它右边的第一个空格,同一个位置最多只能有一个棋子,不能移动棋子的人输。
分析:因为每一行只有20个位置,我们直接用二进制保存,然后计算每个状态的sg值,然后将n行的sg值异或起来就行了,xor=0先手输否则先手胜。
代码:
#include<map> #include<set> #include<cmath> #include<queue> #include<bitset> #include<math.h> #include<vector> #include<string> #include<stdio.h> #include<cstring> #include<iostream> #include<algorithm> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; const int N=4010; const int mod=100000000; const int MOD1=1000000007; const int MOD2=1000000009; const double EPS=0.00000001; typedef long long ll; const ll MOD=1000000007; const int MAX=1000000010; const ll INF=1ll<<55; const double pi=acos(-1.0); typedef double db; typedef unsigned long long ull; int d[25],f[1050000]; int get(int x) { int i,bo=0,w; for (i=1;i<=20;i++) if ((1<<i)-1==x) return 0; memset(d,0,sizeof(d)); for (i=0;i<20;i++) if ((1<<i)>x) break ; else if (((1<<i)&x)==0) { bo=1;w=i; } else if (bo) { d[f[x-(1<<i)+(1<<w)]]=1; } for (i=0;i<25;i++) if (!d[i]) return i; } int main() { int i,j,g,x,n,t,sum,ans; f[0]=0;for (i=1;i<=(1<<20);i++) f[i]=get(i); scanf("%d", &t); while (t--) { scanf("%d", &n);ans=0; for (i=1;i<=n;i++) { scanf("%d", &g);sum=0; for (j=1;j<=g;j++) { scanf("%d", &x);sum+=1<<(20-x); } ans^=f[sum]; } if (ans) printf("YES\n"); else printf("NO\n"); } return 0; }
相关文章推荐
- 18.AJAX及JSON
- BP神经网络的理解
- git创建与管理远程分支
- python格式化输出
- 用Meta标签控制360浏览器默认极速模式打开自己的网站
- C语言测试 IP port 是否可达
- 正则表达式符号理解
- 重写js的replaceAll的方法
- stm32 BOOTLOADER 导出函数给APP调用出现malloc无法分配内存的问题
- iOS9Http请求失败
- jQuery 之 获取页面内容和属性(六)
- 各种开源NLP自然语言处理工具集锦
- ValueAnimator 中文翻译
- ubuntu 16.04 创建android可见的手机wifi
- 2016/07/19 内部类
- mysql数据库查看Client的字符集
- Opencv 注意事项,很有帮助
- 圆角border-radius使用
- let块级作用域
- C 语言中通过脚本获取mac地址