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;
}

 

posted @ 2018-09-30 07:51  Star_Feel  阅读(180)  评论(0编辑  收藏  举报