1. 程式人生 > >POJ 2348 Euclid's Game(博弈)題解

POJ 2348 Euclid's Game(博弈)題解

tac pan tps 題意 \n sin typedef esp cstring

題意:有a,b兩個數字,兩人輪流操作,每次可以選擇兩個之中較小的數字,然後另一個數字減去選擇數字的任意倍數(不能減到負數),直到其中一個為0,不能操作為敗

思路:這題用博弈NP思想,必敗點和必勝點之間的轉化。

我們假設當前狀態為(x,y)其中x>=y,那麽必有以下任一狀態:

1. x < 2 * y:那麽這是只能執行一個操作x - y,如果這個操作之後變成必敗態,那麽當前為必勝態;反之亦然。

2. x >= 2 * y:顯然此時有多種選擇,假設x = k * y,如果x - (k - 1) * y就變成了第一種情況,如果x - k * y就變成了第一種情況操作後的情況,顯然這其中有一個是必勝態,那麽此時情況2必然是必勝情況。

參考:Euclid‘s Game(poj2348+博弈)

代碼:

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
typedef long long ll;
const int maxn = 1e6 + 10
; const int seed = 131; const ll MOD = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; int main(){ ll a, b; while(~scanf("%lld%lld", &a, &b) && a + b){ int times = 0, num = 0; while(a != 0 && b != 0){ times++; if(a > b) swap(a, b); num
= b / a; if(num >= 2) break; b -= a; } if(times & 1) printf("Stan wins\n"); else printf("Ollie wins\n"); } return 0; }

POJ 2348 Euclid's Game(博弈)題解