几道水博弈

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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章