版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34454069/article/details/82841435
分析:
首先,有两个很显然的结论:
1、不考虑除以GCD的情况,就原问题而言(即只是-1),那么胜负只跟偶数的个数有关:若有偶数个偶数,那么后手必胜,反之先手必胜。
证明很简单:很容易想到,奇数的位置其实是可以忽略的,因为当某个人从奇数位-1,另一个人一定可以再在那里-1,又变为了奇数。偶数不能忽略,因为不一定偶数-1后还能再-1(可能就到1了,不能再-1)。所以每个偶数只需1次操作,就能变为奇数,既可以忽略。
换言之,这题就转化为:有N个石子,每次可以拿走一颗,求谁胜谁负。这就显然只跟石子的奇偶性有关了。
2、除以一个奇数,偶数的个数不变。
这证明就更简单了:奇数/奇数=奇数,偶数/奇数=偶数。
所以,其实只有两种情况:
1、直接根据偶数的个数分胜负。
2、尝试所有数除以2
但是,除以2是没那么容易的:
如果A除以2后,A必败,那A不可能去除以2。
如果A除以2后,B必败,那么B一定不会允许A除以2。
所以,除以2如果有效,那么必须在B无法影响的情况下,A一步就达到除以2的条件了。
换言之,只有当前状态有且仅有1个奇数(不为1)的情况下,并且除以2后能够使得对方必败。除以2才有效。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define SF scanf
#define PF printf
#define MAXN 100010
using namespace std;
typedef long long ll;
ll a[MAXN];
int n,now,cnt0,cnt1;
ll gcd(ll x,ll y){
if(y==0)
return x;
return gcd(y,x%y);
}
bool solve(){
int cnt0=0,cnt1=0,now=0;
for(int i=1;i<=n;i++){
if(a[i]%2ll==0)
cnt0++;
else{
cnt1++;
now=i;
}
}
if(cnt1==1&&a[now]!=1){
ll g=0;
a[now]--;
for(int i=1;i<=n;i++)
g=gcd(g,a[i]);
for(int i=1;i<=n;i++)
a[i]/=g;
if(solve()==0)
return 1;
}
if(cnt0%2==1)
return 1;
else
return 0;
}
int main(){
//freopen("game.in","r",stdin);
//freopen("game.out","w",stdout);
SF("%d",&n);
for(int i=1;i<=n;i++)
SF("%lld",&a[i]);
if(solve())
PF("First");
else
PF("Second");
}