POJ 1740 A New Stone Game(博弈)題解
阿新 • • 發佈:2018-09-21
const 證明 one int ios scan space return i++
題意:有n個石子堆,每一個都可以輪流做如下操作:選一個石堆,移除至少1個石子,然後可以把這堆石子隨便拿幾次,隨便放到任意的其他石子數不為0的石子堆,也可以不拿。不能操作敗。
思路:我們先來證明,如果某個石子數有偶數堆,則先手必敗,因為無論先手怎麽做,後手都能模仿先手,最後把石子取光。顯然全是偶數堆是必敗態。如果有奇數堆怎麽辦?我們就把最大的奇數堆取光,然後把其他奇數堆變成偶數堆。但是一定能保證可以嗎?答案是可以。假設奇數堆的石子數為 x1,x2,x3...xn,那麽我們分別給每一堆加上x2-x1,x3-x2...xn-xn-1,我們把這些我們加上的石子數加起來,發現我們一共用了xn-x1個石子,顯然小於等於(xn) -1個石子。
參考:POJ 1740 A New Stone Game 題解《挑戰程序設計競賽》
代碼:
#include<set> #include<map> #include<stack> #include<cmath> #include<queue> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> typedef long long ll; constint maxn = 100 + 10; const int seed = 131; const ll MOD = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; bool vis[maxn]; int main(){ int n; while(~scanf("%d", &n) && n){ memset(vis, false, sizeof(vis)); for(int i = 0; i < n; i++){ int u; scanf("%d", &u); vis[u] = !vis[u]; } int flag = 0; for(int i = 1; i <= 100; i++) if(vis[i]) flag = 1; if(flag) printf("1\n"); else printf("0\n"); } return 0; }
POJ 1740 A New Stone Game(博弈)題解