[hdu 1536 S-Nim] SG 函数

来源:互联网 发布:实体店结算软件 编辑:程序博客网 时间:2024/06/05 02:17

[hdu 1536 S-Nim] SG 函数

题目链接:[hdu 1536 S-Nim]
题意描述:给定K个数s1,s2,,sk表示玩家一次能够能够取得的珠子的个数,然后给M个询问,每个询问都是L堆珠子,每堆珠子的个数分别是h1,h2,,hL,对每个询问,求先手win还是后手win(最后一个取子的win)。
解题思路:裸的SG函数的题目。由s1,s2,,sk可以求出sg函数。然后跟nim一样求一个异或和就OK了。

#include <set>#include <queue>#include <cmath>#include <cstdio>#include <string>#include <cstring>#include <iostream>#include <algorithm>using namespace std;//#pragma comment(linker, "/STACK:1024000000,1024000000")#define FIN             freopen("input.txt","r",stdin)#define FOUT            freopen("output.txt","w",stdout)#define fst             first#define snd             second#define rep(i, s, t)    for(int i = (s); i <= (t); i++)//typedef __int64 LL;//typedef long long LL;typedef pair<int, int> PII;const int MAXN = 100 + 5;const int MX = 10000 + 5;int K, M, L;int s[MAXN], h[MAXN];int sg[MX];bool Hash[MX];void getSG(int SZ) {    memset(sg, 0, sizeof(sg));    rep(i, 1, SZ) {        memset(Hash, false, sizeof(Hash));        rep(j, 1, K) {            if(i - s[j] < 0) break;            Hash[sg[i - s[j]]] = true;        }        rep(j, 0, SZ) {            if(Hash[j] == false) {                sg[i] = j;                break;            }        }    }}int main() {#ifndef ONLINE_JUDGE    FIN;#endif // ONLINE_JUDGE    int xsum;    while(~scanf("%d", &K) && K) {        rep(i, 1, K) {            scanf("%d", &s[i]);        }        sort(s + 1, s + K + 1);        K = unique(s + 1, s + K + 1) - (s + 1);        getSG(MX);        scanf("%d", &M);        rep(i, 1, M) {            scanf("%d", &L);            xsum = 0;            rep(j, 1, L) {                scanf("%d", &h[j]);                xsum ^= sg[h[j]];            }            putchar(xsum ? 'W' : 'L');        }        putchar('\n');    }    return 0;}
1 0