幾道水博弈

1、poj 1067 威佐夫博弈(取石子問題)

課件上的例題,P態和N態與黃金分割點有關。

(0,0)  (1,2) (3,5) (4,7) ... P(必敗態)

滿足 a = i*(sqrt(5.0)+1)/2;  b = a + i;  (a < b)

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
int main() {
    ll a , b , i;
    while(~scanf("%lld%lld",&a,&b)) {
        ll t;
        if(a > b) {
            t = a;
            a = b;
            b = t;    
        } 
        if(floor((b-a)*(sqrt((double)5)+1)/2) == a) printf("0\n");
        else printf("1\n");    
    }    
}


2、poj 2234 Nim博弈

滿足Nim和爲0的狀態是必敗態

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main() {
    int M , ans;
    while(~scanf("%d",&M)) {
        int n;
        scanf("%d",&n);
        ans = n;
        M--;  
        while(M--) {
            scanf("%d",&n);
            ans = n^ans;        
        }
        if(!ans) printf("No\n");
        else printf("Yes\n");  
    }    
}
3、poj 2484 對稱博弈

題意:有一圈硬幣,一次只能拿一個或者拿相鄰的兩個,Alice先拿Bob後拿,給出n個硬幣誰最後拿走剩下的硬幣誰贏

當n<3的時候顯然先手贏,當n>=3時後手贏,把這個圈用軸對稱來看,不管先手拿一個或者兩個,後手都可以拿一個或者兩個繼續把硬幣拆成對稱的兩堆,最後一定是後手拿走最後的硬幣

#include<iostream>
#include<cstdio>
using namespace std;
int main() {
    int n;
    while(cin>>n) {
        if(!n) break;
        if(n<3)
        printf("Alice\n");
        else
        printf("Bob\n");    
    }    
}

4、poj 1704 Nim階梯博弈

階梯博弈詳解:階梯博弈

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int main() {
    int a[1010] , b[1010];
    int T , n , i , ans;
    cin>>T;
    while(T--) {
        cin>>n;
        for(i = 0 ; i < n ; i ++) 
        scanf("%d",&a[i]);
        sort(a , a + n);
        for(i = n - 1 ; i >= 1 ; i --)
        b[i] = a[i] - a[i-1] - 1;
        b[0] = a[0];
        ans = 0;
        for(i = n-1 ; i >= 0 ; i -= 2)    //注意階梯的方向!!!! 
        ans = ans^b[i];
        if(!ans) printf("Bob will win\n");
        else printf("Georgia will win\n");           
    }   
}


5 、從後向前推的博弈

詳解:http://www.cnblogs.com/rainydays/archive/2011/09/07/2169471.html

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
int main() {
    ll left , right , n;
    while(~scanf("%lld",&n)) {
        while(1) {
            n = ceil(n/9.0);      //前一個必勝態的最小數 
            if(n == 1) {
                printf("Stan wins.\n");
                break;    
            }
            n = ceil(n/2.0);
            if(n == 1) {
                printf("Ollie wins.\n");
                break;    
            }
        }
    }
}


發佈了174 篇原創文章 · 獲贊 10 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章