博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 5724:Chess(博弈 + 状压)
阅读量:4686 次
发布时间:2019-06-09

本文共 2838 字,大约阅读时间需要 9 分钟。

 

Chess

 

Problem Description
 
Alice and Bob are playing a special chess game on an n × 20 chessboard. There are several chesses on the chessboard. They can move one chess in one turn. If there are no other chesses on the right adjacent block of the moved chess, move the chess to its right adjacent block. Otherwise, skip over these chesses and move to the right adjacent block of them. Two chesses can’t be placed at one block and no chess can be placed out of the chessboard. When someone can’t move any chess during his/her turn, he/she will lose the game. Alice always take the first turn. Both Alice and Bob will play the game with the best strategy. Alice wants to know if she can win the game.
 
Input
 
Multiple test cases.
The first line contains an integer T(T100), indicates the number of test cases.
For each test case, the first line contains a single integer n(n1000), the number of lines of chessboard.
Then n lines, the first integer of ith line is m(m20), indicates the number of chesses on the ith line of the chessboard. Then m integers pj(1pj20) followed, the position of each chess.
 
Output
 
For each test case, output one line of “YES” if Alice can win the game, “NO” otherwise.
 
Sample Input
 
2
1
2 19 20
2
1 19
1 18
 
Sample Output
 
NO
YES

 

题意:两个人下棋,棋盘有n行20列,每一行有m个棋子分别位于p,棋子只能往右走,如果有相邻的棋子,可以跳过这个棋子,当不能动的时候就输了,问先手能不能赢。

思路:因为只有20列,可以状态压缩,打表枚举一行的所有状态,然后所有行状态的sg值异或起来就是答案。

 

1 #include 
2 #include
3 #include
4 using namespace std; 5 #define N 21 6 7 int sg[1<
= 0; i--) {17 if(now & (1 << i)) {18 int tmp = now;19 for(int j = i - 1; j >= 0; j--) {20 if(!(now & (1 << j))) {21 //这里异或的结果相当于第20-i列的棋子走到第20-j列的状态22 tmp ^= ( (1 << i) ^ (1 << j) );23 vis[sg[tmp]] = 1;24 break;25 }26 }27 }28 }29 for(i = 0; i <= 20; i++)30 if(!vis[i]) {31 sg[now] = i;32 break;33 }34 }35 36 int main()37 {38 sg[0] = 0;39 for(int i = 1; i <= (1 << 20); i++)40 get_sg(i);41 //打表枚举所有状态42 int t;43 scanf("%d", &t);44 while(t--) {45 int n, ans = 0, m, x, y;46 scanf("%d", &n);47 for(int i = 1; i <= n; i++) {48 scanf("%d", &m);49 x = 0;50 for(int j = 1; j <= m; j++) {51 scanf("%d", &y);52 x |= (1 << (20 - y));53 //x = 所有有棋子的列加起来的状态54 }55 ans ^= sg[x];56 //最后的结果是所有行异或57 // printf("ANS : %d\n", ans);58 }59 if(ans == 0) puts("NO");60 else puts("YES");61 }62 return 0;63 }

 

 

 

转载于:https://www.cnblogs.com/fightfordream/p/5757112.html

你可能感兴趣的文章
plist文件的归档,解档
查看>>
Xcode中修改默认文件头部注释
查看>>
从一个针对ASP.NET MVC框架的Controller.Action的请求处理顺序来说整个请求过程。
查看>>
[ZJOI2011]营救皮卡丘
查看>>
首页列表显示全部问答,完成问答详情页布局。
查看>>
pandas read excel文件碰到的一个小问题
查看>>
教师发表职称论文须注意事项
查看>>
libGDX简介
查看>>
《深入理解计算机系统(第三版)》第二章学习总结
查看>>
JavaScript专题——专题三 JavaScript 面向对象
查看>>
快速排序
查看>>
crontab调用python脚本新思路
查看>>
df和du显示的磁盘空间使用情况不一致的原因及处理(文件删除后磁盘空间不释放)...
查看>>
进程与线程的关系与区别
查看>>
第一次使用maven记录
查看>>
SharePoint服务器端对象模型 之 使用CAML进展数据查询
查看>>
Building Tablet PC Applications ROB JARRETT
查看>>
Adobe® Reader®.插件开发
查看>>
存储过程 利用游标 解决复制业务
查看>>
【POJ 3461】Oulipo
查看>>