几道水博弈

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;    
            }
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值