博弈论

SG定理证明
博弈原理
翻硬币游戏
某大佬的小结
k倍动态减法游戏

Codeforces768E Game of Stones

//https://blog.csdn.net/yjf3151731373/article/details/58317950?locationNum=2&fps=1
#include<bits/stdc++.h>
using namespace std;
int n,x,i,j,ans;
int main(){
    scanf("%d",&n);
    for (i=1;i<=n;i++){
        scanf("%d",&x);
        for (j=1;j*(j+1)/2<=x;j++);
        ans^=j-1;
    }
    printf("%s",ans?"NO":"YES");
}

51nod1714 B君的游戏

打表:

#include<bits/stdc++.h>
using namespace std;
int i,i1,i2,i3,i4,i5,i6,i7,j,vis[100000011],sg[110];
int main(){
    freopen("51nod1714.out","w",stdout);
    for (i=1;i<=64;i++){
        for (i1=1;i1<i;i1++)
            for (i2=i1;i2<i;i2++)
                for (i3=i2;i3<i;i3++)
                    for (i4=i3;i4<i;i4++)
                        for (i5=i4;i5<i;i5++)
                            for (i6=i5;i6<i;i6++)
                                for (i7=i6;i7<i;i7++) vis[sg[i1]^sg[i2]^sg[i3]^sg[i4]^sg[i5]^sg[i6]^sg[i7]]=i;
        for (j=0;;j++)
            if (vis[j]!=i){
                sg[i]=j;
                break;
            }
        cout<<sg[i]<<','<<endl;
    }
}

提交程序

#include<bits/stdc++.h>
using namespace std;
int sg[]={0,1,2,4,8,16,32,64,128,255,256,512,1024,2048,3855,4096,8192,13107,16384,21845,27306,32768,38506,65536,
71576,92115,101470,131072,138406,172589,240014,262144,272069,380556,524288,536169,679601,847140,1048576,1072054,
1258879,1397519,2005450,2097152,2121415,2496892,2738813,3993667,4194304,4241896,4617503,5821704,7559873,8388608,
8439273,8861366,11119275,11973252,13280789,16777216,16844349,17102035,19984054,21979742,};
int n,i,sum;
long long ans,x;
int main(){
    scanf("%d",&n);
    for (i=1;i<=n;i++){
        scanf("%lld",&x);
        for (sum=0;x;x-=x&-x,sum++);
        ans^=sg[sum];
    }
    printf("%c",ans?'B':'L');
}

CF 39E What Has Dirichlet Got to Do with That?

//https://blog.csdn.net/v5zsq/article/details/79768931
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
typedef long long ll;
map<P,int>mp;
int a,b,n,ans;
bool check(ll x,int y){
    ll z=1;
    for (;y;y>>=1,x=x*x){
        if (y&1) z=z*x;
        if (x>=n || z>=n) return 1;
    }
    return 0;
}
int dfs(int x,int y){
    if (mp[P(x,y)]) return mp[P(x,y)];
    if (x==1 && check(2,y)) return mp[P(x,y)]=2;
    if (y==1 && check(x,2)) return mp[P(x,y)]=!((n-x)&1);
    if (check(x,y)) return mp[P(x,y)]=1;
    int t1=check(x+1,y),t2=check(x,y+1);
    if (t1 && t2) return mp[P(x,y)]=0;
    if (!t1) t1=dfs(x+1,y);
    if (!t2) t2=dfs(x,y+1);
    if (!t1 || !t2) return mp[P(x,y)]=1;
    if (t1==2 || t2==2) return mp[P(x,y)]=2;
    return mp[P(x,y)]=0;
}
int main(){
    scanf("%d%d%d",&a,&b,&n);
    ans=dfs(a,b);
    if (!ans) printf("Stas");
    else if (ans==1) printf("Masha");
    else printf("Missing");
}

HDU 1079 calendar game

//https://blog.csdn.net/tju_tahara/article/details/52133365
#include<bits/stdc++.h>
using namespace std;
int T,y,m,d;
int main(){
    scanf("%d",&T);
    while (T--){
        scanf("%d%d%d",&y,&m,&d);
        printf("%s\n",(m+d)%2==0 || (m==9 || m==11) && d==30?"YES":"NO");
    }
}

HDU 1525 Euclid’s game

#include<bits/stdc++.h>
using namespace std;
int x,y,t,k;
int main(){
    while (1){
        scanf("%d%d",&x,&y);
        if (!x && !y) return 0;
        k=1;
        if (x<y) swap(x,y);
        while (x%y!=0 && x/y==1) t=x%y,x=y,y=t,k^=1;
        printf("%s wins\n",k?"Stan":"Ollie");
    }
}

HDU 1564 Play a game

//https://www.cnblogs.com/kuangbin/archive/2013/07/22/3204654.html
#include<bits/stdc++.h>
int n;
int main(){
    while (1){
        scanf("%d",&n);
        if (!n) break;
        printf("%s\n",n&1?"ailyanlu":"8600");
    }
}

HDu 2516 取石子游戏

//https://www.cnblogs.com/kuangbin/p/3205070.html
#include<bits/stdc++.h>
using namespace std;
int f[60],n,i;
int main(){
    f[0]=f[1]=1;
    for (i=2;i<60;i++) f[i]=f[i-1]+f[i-2];
    while (~scanf("%d",&n)){
        if (!n) break;
        for (i=0;i<60;i++)
            if (n==f[i]) break;
        printf("%s win\n",i==60?"First":"Second");
    }
}

HDU2897 邂逅明下

//https://blog.csdn.net/u010579068/article/details/47313305
#include<bits/stdc++.h>
using namespace std;
int n,a,b;
int main(){
    while (~scanf("%d%d%d",&n,&a,&b)) printf("%s\n",n%(a+b)<=a && n%(a+b)?"LOST":"WIN");
}

HDU 3032 Nim or not Nim?

网上大多只有一个规律:
当x=4k+1或4k+2时,sg(x)=x;
当x=4k时,sg(x)=x-1;
当x=4k+3时,sg(x)=x+1。
这里我给出证明:
当x=1时,sg(x)=1
假设当x=1..n-1时均成立,那么当x=n时:
1.x=4k,此时sg(1…x-1)已取遍1…4k-2
i)x=4p+4q t=sg(4p)^sg(4q)=(4p-1)^(4q-1) (末2位:11^11=0)
ii)x=(4p+2)+(4q+2) t=sg(4p+2)^sg(4q+2)=(4p+2)^(4q+2)(末2位:10^10=0)
两种情况均取不到4k-1,所以sg(x)=mem(sg(1…x-1))=x-1
2.x=4k+1此时sg(1..x-1)已取遍1…4k
i)x=4p+(4q+1) t=(4p-1)^(4q+1) (末2位11^01=10)
ii)x=(4p+2)+(4q+3) t=(4p+2)^(4q+4)(末2位10^00=10)
两种情况均取不到4k+1,所以sg(x)=mem(sg(1…x-1))=x
x=4k+2和x=4k+3时也同理,证毕。

//https://blog.csdn.net/wxyfennie/article/details/52106268
#include<bits/stdc++.h>
using namespace std;
int T,n,x,ans;
int sg(int x){
    if (x%4==0) return x-1;
    if (x%4==3) return x+1;
    return x; 
}
int main(){
    scanf("%d",&T);
    while (T--){
        scanf("%d",&n);
        ans=0;
        while (n--) scanf("%d",&x),ans^=sg(x);
        printf("%s\n",ans?"Alice":"Bob");
    }
}

HDU 3389 Game

//https://www.cnblogs.com/kuangbin/p/3217994.html
#include<bits/stdc++.h>
using namespace std;
int ans,T,n,i,Case,x;
int main(){
    scanf("%d",&T);
    while (T--){
        scanf("%d",&n);
        ans=0;
        for (i=1;i<=n;i++){
            scanf("%d",&x);
            if (i%6==0 || i%6==2 || i%6==5) ans^=x;
        }
        printf("Case %d: %s\n",++Case,ans?"Alice":"Bob");
    }
}

HDU 3537 Daizhengyang’s coin

//https://www.cnblogs.com/kuangbin/p/3218062.html
#include<bits/stdc++.h>
using namespace std;
int i,n,a[103],ans;
int sg(int x){
    int cnt=0,t=x;
    for (;t;t^=t&(-t),cnt++);
    return (x<<1|1)^(cnt&1);
}
int main(){
    while (~scanf("%d",&n)){
        for (i=0;i<n;i++) scanf("%d",&a[i]);
        ans=0;
        sort(a,a+n);
        n=unique(a,a+n)-a;
        for (i=0;i<n;i++) ans^=sg(a[i]);
        printf("%s\n",!ans?"Yes":"No");
    }
}

HDU 3544 Alice’s Game

//https://blog.csdn.net/hzoi_ztx/article/details/52101666
#include<bits/stdc++.h>
using namespace std;
int T,n,x,y,Case;
long long c1,c2;
int main(){
    scanf("%d",&T);
    while (T--){
        scanf("%d",&n);
        c1=c2=0;
        while (n--){
            scanf("%d%d",&x,&y);
            for (;x>1 && y>1;x>>=1,y>>=1);
            if (x==1) c2+=y-1;
            else c1+=x-1;
        }
        printf("Case %d: %s\n",++Case,c1>c2?"Alice":"Bob");
    }
}

HDU 3951 Coin Game

//https://blog.csdn.net/qinmusiyan/article/details/8015614
#include<bits/stdc++.h>
using namespace std;
int T,n,k,Case;
int main(){
    scanf("%d",&T);
    while (T--) scanf("%d%d",&n,&k),printf("Case %d: %s\n",++Case,(n&1) && k==1 || k>=n?"first":"second");
}

HDU1527 取石子游戏

//https://blog.csdn.net/jason_crawford/article/details/52129969
#include<bits/stdc++.h>
using namespace std;
int n,m,k;
int main(){
    while (~scanf("%d%d",&n,&m)){
        k=(int)(abs(n-m)*0.5*(1+sqrt(5)));
        printf("%d\n",k!=n && k!=m);
    }
}

HDU1517 A multiplication Game

//http://blog.sina.com.cn/s/blog_a16dd6d1010159a5.html
#include<bits/stdc++.h>
using namespace std;
double n;
int main(){
    while (~scanf("%lf",&n)){
        while (n>18) n/=18;
        printf("%s wins.\n",n<=9?"Stan":"Ollie");
    }
}

HDU2486 A simple stone game

//https://blog.csdn.net/qq_29480875/article/details/52742403
#include<bits/stdc++.h>
using namespace std;
const int N=2000003;
int T,Case,ans,i,k,n,a[N],b[N],j;
int main(){
    scanf("%d",&T);
    while (T--){
        scanf("%d%d",&n,&k);
        printf("Case %d: ",++Case);
        if (n<=k){
            printf("lose\n");
            continue;
        }
        a[0]=b[0]=1;
        for (i=0,j=0;a[i]<n;){
            i++;
            a[i]=b[i-1]+1;
            while (a[j+1]*k<a[i]) j++;
            if (a[j]*k<a[i]) b[i]=a[i]+b[j];
            else b[i]=a[i];
        }
        if (a[i]==n){
            printf("lose\n");
            continue;
        }
        ans=0;
        while (n){
            if (n>=a[i]) n-=a[i],ans=a[i];
            i--;
        }
        printf("%d\n",ans);
    }
}

HDU4315 Climbing the Hill

//https://blog.csdn.net/clover_hxy/article/details/53727773
//https://blog.csdn.net/fsss_7/article/details/51889949
#include<bits/stdc++.h>
using namespace std;
int n,k,i,ans,a[1003],b[1003];
int main(){
    while (~scanf("%d%d",&n,&k)){
        for (i=1;i<=n;i++) scanf("%d",&a[i]);
        if (k==1){
            printf("Alice\n");
            continue;
        }
        if (k!=2) a[0]=-1;
        else a[0]=0;
        ans=0;
        for (i=1;i<=n;i++) b[n-i+1]=a[i]-a[i-1]-1;
        for (i=1;i<=n;i+=2) ans^=b[i];
        printf("%s\n",ans?"Alice":"Bob");
    }
}

HDU1538 A Puzzle for Pirates

//https://blog.csdn.net/acm_cxlove/article/details/7853916#comments
#include<bits/stdc++.h>
using namespace std;
int n,m,p,T;
void solve(int n,int m,int p){
    if (n<=m*2+1){
        if (p!=n && (n&1)==(p&1)) printf("1\n");
        else if (p==n) printf("%d\n",m-(n-1)/2);
        else printf("0\n");
        return;
    }
    int t=n-2*m;
    for (int i=1;i<15;i++)
        if (t==1<<i){
            printf("0\n");
            return;
        }
    for (int i=2;i<15;i++)
        if (t<1<<i){
            if (2*m+(1<<i-1)<p && p<2*m+(1<<i)) printf("Thrown\n");
            else printf("0\n");
            return;
        }
}
int main(){
    scanf("%d",&T);
    while (T--){
        scanf("%d%d%d",&n,&m,&p);
        solve(n,m,p);
    }
}

HDU3404 switch lights

//https://blog.csdn.net/acm_cxlove/article/details/7836764
#include<bits/stdc++.h>
using namespace std;
int mp[2][2]={{0,0},{0,1}},T,n,ans,x,y;
int Pow(int x,int y){
    if (x<2) return mp[x][y];
    int a=0;
    for (;;a++)
        if ((1<<(1<<a))<=x && x<(1<<(1<<a+1))) break;
    int m=1<<(1<<a),p=x/m,s=y/m,t=y%m,d1=Pow(p,s),d2=Pow(p,t);
    return (m*(d1^d2))^Pow(m>>1,d1);
}
int Mul(int x,int y){
    if (x<y) return Mul(y,x);
    if (x<2) return mp[x][y];
    int a=0;
    for (;;a++)
        if ((1<<(1<<a))<=x && x<(1<<(1<<a+1))) break;
    int m=1<<(1<<a),p=x/m,q=x%m,s=y/m,t=y%m,c1=Mul(p,s),c2=Mul(p,t)^Mul(q,s),c3=Mul(q,t);
    return (m*(c1^c2))^c3^Pow(m>>1,c1);
}
int main(){
    scanf("%d",&T);
    while (T--){
        scanf("%d",&n);
        ans=0;
        while (n--) scanf("%d%d",&x,&y),ans^=Mul(x,y);
        printf("%s\n",ans?"Have a try, lxhgww.":"Don't waste your time.");
    }
}

51nod1661 黑板上的游戏

//https://www.cnblogs.com/zhangchengc919/p/5822981.html
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100003;
int n,i;
double tmp;
ll sum,le,a[N],s[N],f,k;
ll sg(ll x){
    if (x%k==1) return sg(x/k);
    ll le=x/k;
    if (le*k!=x) le++;
    return x-le;
}
int main(){
    scanf("%d%lld",&n,&k);
    for (i=1;i<=n;i++) scanf("%lld",&a[i]),s[i]=sg(a[i]),sum^=s[i];
    printf("%s",sum?"Alice":"Bob");
    if (sum){
        tmp=k*1.0/(k-1);
        for (i=n;i;i--){
            if (a[i]==1) continue;
            sum^=s[i];
            f=ceil(tmp*sum);
            le=a[i]/k;
            if (le*k!=a[i]) le++;
            while (1){
                if (le<=f && f<a[i] && sg(f)==sum){
                    printf(" %d %lld",i,f);
                    return 0;
                }
                f=f*k+1;
                if (f>a[i]) break;
            }
            sum^=s[i];
        }
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值