bzoj 1115 [POI2009]石子游戏Kam 阶梯博弈
1115: [POI2009]石子游戏Kam
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1174 Solved: 717
[Submit][Status][Discuss]
Description
有N堆石子,除了第一堆外,每堆石子个数都不少于前一堆的石子个数。两人轮流操作每次操作可以从一堆石子中移走任意多石子,但是要保证操作后仍然满足初始时的条件谁没有石子可移时输掉游戏。问先手是否必胜。
Input
第一行u表示数据组数。对于每组数据,第一行N表示石子堆数,第二行N个数ai表示第i堆石子的个数(a1<=a2<=……<=an)。 1<=u<=10 1<=n<=1000 0<=ai<=10000
Output
u行,若先手必胜输出TAK,否则输出NIE。
Sample Input
2
2
2 2
3
1 2 4
2
2 2
3
1 2 4
Sample Output
NIE
TAK
TAK
题解:阶梯博弈的模板的题。
阶梯博弈必须倒着来,奇偶之间相互抵消,最后一堆单独,不改变胜败状态。
1 #include<cstring> 2 #include<cmath> 3 #include<cstdio> 4 #include<algorithm> 5 #include<iostream> 6 7 #define N 1007 8 9 #define Wb putchar(' ') 10 #define We putchar('\n') 11 #define rg register int 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 17 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 inline void write(int x) 21 { 22 if(x<0) putchar('-'),x=-x; 23 if (x==0) putchar(48); 24 int num=0;char c[15]; 25 while(x) c[++num]=(x%10)+48,x/=10; 26 while(num) putchar(c[num--]); 27 } 28 29 int n; 30 int a[N]; 31 32 int main() 33 { 34 rg T=read(),res; 35 while(T--) 36 { 37 n=read(),res=0; 38 for (rg i=1;i<=n;i++) a[i]=read(); 39 for (rg i=n;i>1;i-=2) res^=(a[i]-a[i-1]); 40 if (n&1) res^=a[1]; 41 if (res) puts("TAK"); 42 else puts("NIE"); 43 } 44 }