hdu2176取(m堆)石子游戏 nim hdu1848Fibonacci again and again sg

1Bash Game
n%(m+1)!=0,先取者win


2Wythoff Game
(a,b)
k=(b-a);
if(a==(int)(k*(1+sqrt(5.0))/2)) 后取者win


3Nimm Game
(a,b,c,d...)

if(a^b^c^d^..==0)后取者win



hdu1848

//http://wenku.baidu.com/link?url=o67TvcWu5jBOoqhfj0wlgoJd735EBv3fq8KmXi0nS0iMMBRa378DENdT5i0pdlN9knrJgddDHqprKbn8s9jLgolTVwOItBr7rlgEhMb_OaS
//对于nim游戏的某个位置(x1,x2,x3),当且仅当它各部分的nim-sum等于0时(即x1⊕x2⊕x3=0),则当前位于必败点
#include<iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int fb[20],sg[1005];
bool b[1005];
int n,m,p,k;
void getsg(){
    fb[1]=1;fb[2]=2;
    for(k=3;;k++){
        fb[k]=fb[k-1]+fb[k-2];
        if(fb[k]>1000)break;
    }
    for(int i=1;i<=1000;i++){
        memset(b,true,sizeof(b));
        for(int j=1;j<k;j++){
            if(i<fb[j])break;
            b[sg[i-fb[j]]]=false;//i-fb[j]必败
        }
        for(int j=0;j<=1000;j++)
            if(b[j]){
                sg[i]=j;/
                break;
            }
    }
}
int main(){
    getsg();
    while(scanf("%d%d%d",&n,&m,&p)&&(n+m+p)){
        int tmp=0;
        tmp^=sg[n]^sg[m]^sg[p];
        if(tmp)cout<<"Fibo\n";
        else cout<<"Nacci\n";
    }
    return 0;
}

hdu2176

/*
思路:1)如若给出 的是必败状态:a1^a2^......^an=0,则先手不会有任何可能获得胜利;
           2)若给出的是必胜状态:a1^a2^.......^an=k,(其中k不为零),那么我们的目的是要把必胜状态
        转化为必败状态从 而使得先手胜利。若a1^a2^...^an!=0,一定存在某个合法的移动,将ai
       改变成ai'后满足a1^a2^...^ai'^...^an=0。若a1^a2^...^an=k,则一定存在某个ai,
       它的二进制 表示在k的最高位上是1(否则k的最高位那个1是怎么得到的)。这时ai^k<ai一定
       成立。则我们可以将ai改变成ai'=ai^k,此时a1^a2^...^ai'^...^an=a1^a2^...^an^k=0。
       */
#include <iostream>
#include <cstdio>
using namespace std;
const int N=200009;
int main(){
    int m;
    while(scanf("%d",&m)&&m){
        int a[N],ans=0;
        for(int i=0;i<m;i++){
            scanf("%d",a+i);
            ans^=a[i];
        }
        if(!ans)cout<<"No"<<endl;
        else{
            cout<<"Yes"<<endl;
            for(int i=0;i<m;i++){
                if((a[i]^ans)<a[i])
                    cout<<a[i]<<' '<<(a[i]^ans)<<endl;
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值