博弈

bash博弈:

一堆石子,有n个石子,每一次最多取k个,问你谁先获胜。 直接判断 n % (k +1 )是否为0,如果是0的话就是奇异局(只要对面不是傻逼的话就一定会输的局,否则就是对面赢。

题目链接:https://cn.vjudge.net/contest/257365#problem/A

AC代码:

#include<iostream>
#include<string>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
#include<stdio.h>
using namespace std;
# define maxn 1000000+10
# define inf 0x3f3f3f3f
# define ll long long
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,m;
scanf("%d%d",&n,&m);
if(m>=n)printf("A\n");
else {
if(n%(m+1))printf("A\n");
else printf("B\n");
}
}
return 0;

}

尼姆博弈:

有n堆石子,每一次可以拿任意多个,问你谁拿最后一个。

解题方法:直接将每一堆的石子异或,如果最终结果是0的话就代表是奇异局,否则就是非奇异局。

题目链接:https://cn.vjudge.net/contest/257365#problem/C

AC代码:

#include<iostream>
#include<string>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
#include<stdio.h>
using namespace std;
# define maxn 1000000+10
# define inf 0x3f3f3f3f
# define ll long long
int vis[maxn];
int ans[maxn];
int main()
{
int n;
scanf("%d",&n);
int temp;
scanf("%d",&temp);
for(int i=2;i<=n;i++){
int t;
scanf("%d",&t);
temp=temp^t;
}
if(temp==0)printf("B\n");
else printf("A\n");
    return 0;
}

威佐夫博弈:

两堆石子,每一个可以从一堆里面拿任意个或者从两堆里面拿相同的个数,问你最后谁拿完。

判断方法:如果满足 最大值和最小值的差值乘以黄金分割率等于最小值,那么当前的局面就是奇异局,否则就是非奇异局。

题目链接:https://cn.vjudge.net/contest/257365#problem/D

AC代码:

#include<iostream>
#include<string>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
#include<stdio.h>
using namespace std;
# define maxn 1000000+10
# define inf 0x3f3f3f3f
# define ll long long
# define gold (sqrt(5.0)+1.0)/2.0
ll maxx(ll t1,ll t2){
if(t1>t2)return t1;
return t2;
}
ll minn(ll t1,ll t2){
if(t1>t2)return t2;
return t1;
}
int main()
{
    ll T;        ll n,m;
    while(~scanf("%lld%lld",&n,&m))
    {


        ll a,b;
        a=maxx(n,m);
        b=minn(n,m);
        int t=(a-b)*gold;
       // cout<<a<<" "<<b<<" "<<t<<" "<<gold<<endl;
        if(b==t)printf("0\n");
        else printf("1\n");
    }
    return 0;
}

分割线/-----------------------------------------------------------------------------------------------------------------------------------/

上面这些只是基本的模型,如果是稍微修改题意就可能套不上模板了,比如说下面这个题。

https://cn.vjudge.net/contest/257365#problem/B

这个时候就需要用到sg函数了,先介绍mex函数,这个函数的作用是先找到第一个在当前的区间内非负的值。

比如说,mex[1 3 5  7] = 0 . mex[ 1 ] = 0 ,mex[2 5 7 8]= 0.mex[ 0] =1;

然后再开始介绍sg,就拿例题作解释。

当只有一颗石子的时候,它的后继状态只有0 (1-1=0) ,sg[1]=mex(sg[0])=1.

当只有两颗石子的时候,他的后继状态变成了1(2-1=1),sg[2]=mex(sg[1])=0,那么这个时候就是奇异局了,也就是说只要对面不是傻逼的话,自己就一定会输。

当只有三颗石子的时候,他的后继状态变成了2(3-1=2),0(3-3=0),所以说,sg[3]=mex(sg[2],sg[0])=2.

以此类推,就可以推出当石子数为n的时候是不是博弈局了。一般的话如果数据量不大的话,可以直接暴力,如果数据量大的话,就可以通过sg打表找规律了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值