题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5795
题意:一个n堆的取石子游戏,每次可以取一堆中的任意个,或者将当前堆分为三个非空堆。求先手/后手必胜。
思路:打表sg函数找规律。hihocoder上面有类似的题目,不过那个是分为两堆。
http://hihocoder.com/problemset/problem/1173
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <utility>
using namespace std;
#define rep(i,j,k) for (int i=j;i<=k;i++)
#define Rrep(i,j,k) for (int i=j;i>=k;i--)
#define Clean(x,y) memset(x,y,sizeof(x))
#define LL long long
#define ULL unsigned long long
#define inf 0x7fffffff
#define mod 100000007
//int sg[1009];
//
//void init()
//{
// sg[0] = 0;
// bool f[1009];
// rep(i,1,100)
// {
// Clean(f,false);
// rep(j,1,i)
// f[ sg[i-j] ] = true;
// if ( i >= 3 )
// {
// rep(j,1,i-2)
// rep(k,1,i-2)
// if ( j+k < i )
// f[ sg[j] ^ sg[k] ^ sg[i-j-k] ] = true;
// }
// int j = 0;
// while ( f[j] ) j++;
// sg[i] = j;
// cout<<i<<" : "<<sg[i]<<endl;
// }
//}
int main()
{
//init();
int T,n,temp;
cin>>T;
while(T--)
{
int ans = 0;
scanf("%d",&n);
rep(i,1,n)
{
scanf("%d",&temp);
if ( temp % 8 == 0 )
ans ^= temp-1;
else if ( temp % 8 == 7 )
ans ^= temp + 1;
else ans ^= temp;
}
puts( ans ? "First player wins." : "Second player wins." );
}
return 0;
}