【HDU】5724 Chess
2016-07-22 20:52
453 查看
Chess
题目链接
Chess题目大意
每行有若干个棋子,两个人分别移动,每个人每次可以移动一次,规则:当右边没有棋子时,直接移动到右边。
当右边有棋子时,跳过这些棋子直接移动到最右边的空地
一个格子只能放一个棋子
题解
因为每行只有20列,求出每行的SG函数值,最后根据SG定理直接求异或就行了。代码
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int T,p,sg[(1<<20)+5],n,m; int Check(int k,int p) { for (int i=p-1;i>=0;i--) if (!(k&(1<<i))) return k^(1<<i)^(1<<p); return -1; } int dfs(int k) { if (sg[k]!=-1) return sg[k]; bool vis[25]={0}; for (int i=19;i>0;i--) if (k&(1<<i)) { int t=Check(k,i); if (t!=-1) vis[dfs(t)]=1; } for (int i=0;i<25;i++) if (!vis[i]) return sg[k]=i; } int main() { memset(sg,-1,sizeof(sg)); int k=(1<<20) -1; sg[k]=0; for (int i=0;i<20;i++) { k=(1<<(20-i-1))^k; sg[k]=0; } k=(1<<20)-1; for (int i=0;i<20;i++) { k^=(1<<i); dfs(k); } scanf("%d",&T); while (T--) { int ans=0; scanf("%d",&n); for (int i=0;i<n;i++) { scanf("%d",&m); k=0; for (int j=0;j<m;j++) { scanf("%d",&p); k=k^(1<<(20-p)); } ans^=sg[k]; } if (ans) printf("YES\n"); else printf("NO\n"); } return 0; }
相关文章推荐
- centos下安装JDK8的方法
- 中文分词工具
- 经纬度坐标生成点要素
- J2EE进阶(八)Hibernate与延迟加载机制探究
- HDU 5742 It's All In The Mind
- js-表单验证
- nyoj 119 士兵杀敌(三) <模板RMQ--静态数组时求最大最小值>
- 一、Java数据类型
- Timus 1052 Rabbit Hunt
- linux软件安装简介(apt和dpkg)
- 如何在 Linux 上永久挂载一个 Windows 共享
- 步态识别综述(一)
- hdu4081 Qin Shi Huang's National Road System(次小生成树)
- tomcat设置默认项目
- android studio listview控件基础 代码
- SDUT2118数据结构实验之链表三:链表的逆置
- Mac brew安装mysql之后无法启动mysql
- HDU 1215 七夕节
- RDD Transformation算子分类
- SPOJ RMQSQ Range Minimum Query 《RMQ》