sg函数&&子状态的讨论
题目链接:https://cn.vjudge.net/contest/269933#problem/H
具体思路:首先,这是一个公平的比赛,并且是两个人参与,两个人都足够聪明,并且可以通过有限步结束比赛,所以可以通过sg函数解决,注意这个题的不同,假设当前的某一堆堆数是5,如果分成每堆为2,他的子状态是2 2 1,和之前做过的子状态不同,之前做的题拿掉的就相当于扔掉了,而这个题并没有。
1 #include<iostream>
2 #include<string>
3 #include<iomanip>
4 #include<stack>
5 #include<queue>
6 #include<map>
7 #include<vector>
8 #include<cmath>
9 #include<stdio.h>
10 #include<cstring>
11 using namespace std;
12 # define ll long long
13 # define maxn 2000+100
14 # define inf 0x3f3f3f3f
15 int ans[maxn];
16 int vis[maxn];
17 int main()
18 {
19 ans[0]=0;
20 for(int i=1; i<=2000; i++)
21 {
22 memset(vis,0,sizeof(vis));
23 for(int j=1; j<i; j++)
24 {
25 int temp=i/j;
26 if(temp%2==0)vis[ans[i%j]]=1;//如果按照每一堆j个,如果有2堆,那么他们的异或是0,如果有一堆,他们的异或就是本身,所以这个地方可以化简一下,直接判断奇数还是偶数就可以了。
27 else vis[ans[i%j]^ans[j]]=1;
28 }
29 for(int j=0; j<=2000; j++)
30 {
31 if(vis[j]==0)
32 {
33 ans[i]=j;
34 break;
35 }
36 }
37 }
38 int n;
39 int temp;
40 int t=0;
41 scanf("%d",&n);
42 for(int i=1; i<=n; i++)
43 {
44 scanf("%d",&temp);
45 t^=ans[temp];
46 }
47 if(t)printf("First\n");
48 else printf("Second\n");
49 return 0;
50 }
51