BZOJ1115: [POI2009]石子游戏Kam
【传送门:BZOJ1115】
简要题意:
给出n堆石子,除第一堆石子外,其他堆的石子数都不能少于前一堆的石子数。现有两人轮流取石子,每次能拿任意一堆的任意数量的石子,但要保证拿完以后仍满足每堆石子数不能少于前一堆的石子数。若不能再取石子则输掉比赛,询问先手是否必胜
题解:
阶梯博弈
因为每堆石子数都不能少于前一堆石子数,所以a[i]-a[i-1]>=0
而且从第i堆中拿x个石子,那么第i堆与第i-1堆的差-x,第i+1堆与第i堆的差+x,就相当于将石子向后推了一格
那么就转换为能将任意一堆的石子向后推,不能再推的人输掉比赛
因为阶梯博弈还有个性质:相当于奇数阶梯玩NIM游戏,就直接异或,然后判断就行了
参考代码:
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int a[1100]; int main() { int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int ans=0; for(int i=n;i>=1;i-=2) { ans=ans^(a[i]-a[i-1]); } if(ans==0) printf("NIE\n"); else printf("TAK\n"); } return 0; }
渺渺时空,茫茫人海,与君相遇,幸甚幸甚