【博弈】AGC010D Decrementing
阿新 • • 發佈:2018-12-11
分析:
首先,有兩個很顯然的結論: 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");
}