1. 程式人生 > 其它 >2021.7.20 義烏模擬賽 T4 遊戲

2021.7.20 義烏模擬賽 T4 遊戲

首先這道題你發現所有異或和不變所以當異或和為\(0\)時一定平局。
當異或和不為\(0\)時我們只要考慮最高位即可。
具體的,我們將擁有這個最高位的置為\(1\),沒有的置為\(0\),然後就變成了如何讓先手取到\(1\)的個數為奇數。
這個東西寫個dp就可以\(O(n^2)\)了。
然後把dp打表輸出規律就可以\(O(n)\)得到答案了。
code:

#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define ll long long
#define db double
#define N 50000
#define M 1000
#define mod 1000000007
#define eps (1e-7)
#define U unsigned int
#define it iterator
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
using  namespace std;
int n,m,T,A[N+5],now,B[N+5];
I int check(int x,int y){
	re int i,l=x,r=y;now=0;while(l<r&&B[l]==B[r])l++,r--;for(i=l+1;i<=r;i+=2) if(B[i]^B[i-1]) return 0;for(i=x;i<=y;i++)now+=B[i];return !(now%4);
}
I void read(int &x){char s=Gc();x=0;while(s<'0'||s>'9') s=Gc();while(s>='0'&&s<='9') x=x*10+s-48,s=Gc();}
I void Solve(){
	re int i;now=0;for(i=1;i<=n;i++) read(A[i]),now^=A[i];if(!now){puts("Draw");return;}if(n%2==0){puts("First");return;}
	for(i=30;~i;i--) if(now&(1<<i)){now=i;break;} for(i=1;i<=n;i++) B[i]=(A[i]>>now)&1;puts((B[1]&&check(2,n))||(B[n]&&check(1,n-1))?"First":"Second");
}
int main(){
	freopen("d.in","r",stdin);freopen("d.out","w",stdout);
	scanf("%d",&T);while(T--) scanf("%d",&n),Solve();
}