1. 程式人生 > >【bzoj1115】[POI2009]石子遊戲Kam(博弈論)

【bzoj1115】[POI2009]石子遊戲Kam(博弈論)

amp 分享 b- 傳送門 tchar display tmp owb div

  題目傳送門:https://www.lydsy.com/JudgeOnline/problem.php?id=1115

  觀察問題,我們能發現前後相鄰兩堆石子的數量差一定非負,而我們在第i堆石子中移走k個石子,那麽第i堆與第i-1堆石子的數量差就減少k,第i+1堆與第i堆的數量差增加k。這樣就轉化為了一個經典的博弈論遊戲:階梯遊戲。我們把第i堆石子移走k個,那麽就相當於把階梯上第i堆與第i-1堆石子的差那一級移k個石子到第i+1堆與第i堆的差那一級上(往下移一級)。於是就有一個結論:階梯遊戲的結果=拿奇數梯的石子玩NIM遊戲。

  代碼:

技術分享圖片
#include<cstdio>
#include
<cmath> #include<cstdlib> #include<cstring> #include<ctime> #include<string> #include<iostream> #include<algorithm> #include<queue> #include<vector> #include<map> #define ll long long #define ull unsigned long long #define max(a,b) (a>b?a:b) #define
min(a,b) (a<b?a:b) #define lowbit(x) (x& -x) #define mod 1000000007 #define inf 0x3f3f3f3f #define eps 1e-18 #define maxn 2000010 inline ll read(){ll tmp=0; char c=getchar(),f=1; for(;c<0||9<c;c=getchar())if(c==-)f=-1; for(;0<=c&&c<=9;c=getchar())tmp=(tmp<<3)+(tmp<<1
)+c-0; return tmp*f;} inline ll power(ll a,ll b){ll ans=1; for(;b;b>>=1){if(b&1)ans=ans*a%mod; a=a*a%mod;} return ans;} inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline void swap(int &a,int &b){int tmp=a; a=b; b=tmp;} using namespace std; int a[1010]; int n; int main() { int t=read(); while(t--){ n=read(); ll tmp=0; for(int i=1;i<=n;i++)a[i]=read(); for(int i=n;i>=1;i-=2) tmp^=a[i]-a[i-1]; if(tmp)printf("TAK\n"); else printf("NIE\n"); } }
bzoj1115

【bzoj1115】[POI2009]石子遊戲Kam(博弈論)