【HDU5724 2016 Multi-University Training Contest 1B】【博弈 SG函数】Chess 棋子跳棋向右移 先后手胜负博弈
来源:互联网 发布:windows无法识别u盘 编辑:程序博客网 时间:2024/06/16 09:59
Chess
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1369 Accepted Submission(s): 597
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 integerT(T≤100) , indicates the number of test cases.
For each test case, the first line contains a single integern(n≤1000) , the number of lines of chessboard.
Thenn lines, the first integer of ith line is m(m≤20) , indicates the number of chesses on the ith line of the chessboard. Then m integers pj(1≤pj≤20) followed, the position of each chess.
The first line contains an integer
For each test case, the first line contains a single integer
Then
Output
For each test case, output one line of “YES” if Alice can win the game, “NO” otherwise.
Sample Input
212 19 2021 191 18
Sample Output
NOYES
Author
HIT
Source
2016 Multi-University Training Contest 1
#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<ctype.h>#include<math.h>#include<set>#include<map>#include<vector>#include<queue>#include<bitset>#include<algorithm>#include<time.h>using namespace std;void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }#define MS(x,y) memset(x,y,sizeof(x))#define MC(x,y) memcpy(x,y,sizeof(x))#define MP(x,y) make_pair(x,y)#define ls o<<1#define rs o<<1|1typedef long long LL;typedef unsigned long long UL;typedef unsigned int UI;template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }const int N = 0, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;int casenum, casei;int n, m;int b[24];int sg[1 << 20];int no[24];void init(){for (int i = 0; i < 20; ++i)b[i] = 1 << i;int top = 1 << 20;for (int i = top - 1; ~i; --i){MS(no, 1);int blk = -1;for (int j = 19; ~j; --j){if (i >> j & 1){if (~blk){int nxt = i ^ b[j] ^ b[blk];no[sg[nxt]] = 0;}}else blk = j;}while (!no[sg[i]])++sg[i];}}int main(){init();scanf("%d", &casenum);for (casei = 1; casei <= casenum; ++casei){scanf("%d", &n);int SG = 0;for (int i = 1; i <= n; ++i){int g; scanf("%d", &g);int sta = 0;while (g--){int x; scanf("%d", &x); --x;sta |= b[x];}SG ^= sg[sta];}puts(SG ? "YES" : "NO");}return 0;}/*【题意】n*20的棋盘每行有若干个棋子。A和B轮流做游戏。每次可以任选一行,把该行的某个棋子按照一定的规则移动。最后谁不能移动就输了。问先手胜负情况。移动规则是这样的——如果选定棋子右侧为空,则直接移过去。否则把该棋子移动至右侧非空的第一个位置。【类型】博弈 SG函数【分析】这题对于每行,显然都可以认定为一个独立的子游戏。行状态最多只有2^20,我们对其做个SG函数预处理。然后把所有行的SG值异或起来,非零则先手必胜。问题是——如何求SG值呢?我们发现——1,棋子只会往右移动,如果我们把b[i]定义为1<<i的话,右移操作只会使得状态编号越变越大。——于是我们按照状态数由大到小的顺序处理SG函数2,每个状态的后继状态最多只有20个,这意味着——我们可以快速算出SG函数,且SG函数的值限定在[0,20]之间【时间复杂度&&优化】O(1 << 20 * 20)*/
0 0
- 【HDU5724 2016 Multi-University Training Contest 1B】【博弈 SG函数】Chess 棋子跳棋向右移 先后手胜负博弈
- HDU5724 Chess 阶梯博弈变形 2016 Multi-University Training Contest 1
- (HDU 5724)2016 Multi-University Training Contest 1 Chess(SG函数、博弈)
- HDU 5274 Chess(SG博弈)---2016 Multi-University Training Contest 1
- HDU 5274 Chess(SG博弈)---2016 Multi-University Training Contest 1
- HDU5724 2016 Multi-University Training Contest 1 (SG+预处理)
- hdu5724 Chess【博弈+sg函数】
- (HDU 5795)2016 Multi-University Training Contest 6 A Simple Nim (SG函数、博弈)
- 2016 Multi-University Training Contest 6 1003 A Simple Nim (博弈sg函数)
- 2016 Multi-University Training Contest 1 1002 Chess (博弈+状态压缩)
- 2016 Multi-University Training Contest 1 1002 hdu 5724 博弈
- hdu 5299 Circles Game 2015 Multi-University Training Contest 1 计算几何+博弈SG函数 圆的扫描线
- hdu5724 博弈+SG函数+状压 多校1
- 2016 Multi-University Training Contest 1 1002 Chess
- HDU 5724 Chess (from: 2016 Multi-University Training Contest 1)
- ACM2016多校联赛1B hdu5724 Chess(博弈)
- hdu5724 Chess(博弈)
- hdu5724 Chess (博弈+状压)
- hadoop使用心得总结
- [CityHunter]游戏流程设计及技术要点
- 【CDP-云设计模式】第5章,3.私有分配模式(Private Distribution Pattern)
- 远程host改变后,本机ssh相应修改
- ambari基础篇
- 【HDU5724 2016 Multi-University Training Contest 1B】【博弈 SG函数】Chess 棋子跳棋向右移 先后手胜负博弈
- golang开发环境配置(Linux)
- 遇到的兼容性能问题
- 局域网与广域网,以太网与点对点链路
- 仿照QQ的删除效果
- Asp.net +jQuery +ajax 传参问题
- android listView嵌套gridview的使用心得
- 算法:递归总结(2)例子
- 电气学习笔记(SSCNC)1 点动、互锁和自动往返