POJ 3537 multi-sg 暴力求SG
长为n的一列格子,轮流放同种棋子,率先使棋子连成3个者胜。
可以发现每次放一个棋子后,后手都不能放在[x-2,x+2]这个区间,那么相当于每次放棋将游戏分成了两个,不能放棋者败。
暴力求SG即可
/** @Date : 2017-10-14 22:50:13 * @FileName: POJ 3537 multi-sg 暴力SG.cpp * @Platform: Windows * @Author : Lweleth (SoungEarlf@gmail.com) * @Link : https://github.com/ * @Version : $Id$ */ #include <stdio.h> #include <iostream> #include <string.h> #include <algorithm> #include <utility> #include <vector> #include <map> #include <set> #include <string> #include <stack> #include <queue> #include <math.h> //#include <bits/stdc++.h> #define LL long long #define PII pair<int ,int> #define MP(x, y) make_pair((x),(y)) #define fi first #define se second #define PB(x) push_back((x)) #define MMG(x) memset((x), -1,sizeof(x)) #define MMF(x) memset((x),0,sizeof(x)) #define MMI(x) memset((x), INF, sizeof(x)) using namespace std; const int INF = 0x3f3f3f3f; const int N = 1e5+20; const double eps = 1e-8; int sg[N]; int dfs(int x) { if(x < 0) return 0; if(sg[x] != -1) return sg[x]; int vis[2010]; MMF(vis); for(int i = 1; i <= x; i++) vis[dfs(i - 3) ^ dfs(x - i - 2)] = 1; for(int i = 0; ;i++) if(!vis[i]) return sg[x] = i; return sg[x]; } int main() { int n; while(cin >> n) { MMG(sg); int ans = dfs(n); printf("%d\n", ans?1:2); } return 0; }