HDU 5724 (博弈)

来源:互联网 发布:午夜美女直播软件 编辑:程序博客网 时间:2024/05/27 19:25

题目链接:点击这里

题意:n*20的棋盘,每一行有若干棋子, 每次可以把一枚棋子向右放到离他最近的空格子,最先不能操作的失败。问先手是否必胜。

相当于是一个NIM游戏,每一行是一个独立的游戏,每一行异或起来即可。可以预处理一行中所有状态的sg值。

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <cmath>#include <map>using namespace std;#define maxn 1500000#define INF 1111int sg[maxn];bool vis[55];int n, m;void init () {    sg[0] = sg[1] = 0;    for (int i = 2; i < (1<<20); i++) {         memset (vis, 0, sizeof vis);        int l = -1;        for (int j = 0; j < 20; j++) {            if (i&(1<<j)) {                if (l >= 0) vis[sg[i^(1<<j)^(1<<l)]] = 1;            }            else                 l = j;        }        for (int j = 0; j < 55; j++) if (!vis[j]) {            sg[i] = j;            break;        }    }}int main () {    init ();    int t;    scanf ("%d", &t);    while (t--) {        scanf ("%d", &n);        int ans = 0;        for (int i = 0; i < n; i++) {            int tmp = 0;            scanf ("%d", &m);            while (m--) {                int bit; scanf ("%d", &bit);                tmp |= (1<<(20-bit));            }            ans ^= sg[tmp];        }        printf ("%s\n", ans ? "YES" : "NO");    }    return 0;}
0 0