博弈论

尼姆($nim$)游戏:

P2197 【模板】Nim 游戏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

对于博弈论游戏,如果当前的选手具有控制权的话,那么当前选手是必赢的,也就是当前选手做出的这步选择后,之后的局面都是在其预料之中的,换句话说,先掌握了控制权即赢. 考虑什么情况下是控制权,对于一个局面,我们最终的局面一定是 0 0 0 0....,其异或和为 $0$.

那么存在定义异或和为的局面为局面 $0$,其余局面为局面 $1$,若当前局面为 $0$ 局面,那么下一步一定会变成 $1$ 局面, 若当前局面为 $1$ 局面,那么当前局面可根据选手选择变成 $0$ 或者 $1$即当前局面为选手掌握控制权局面,则胜出

故: 若一开始的局面为 $0$ 局面那么后手一定掌握控制权,即后手赢,否则先手赢

#include<bits/stdc++.h>
using namespace std;
void solve(){
    int n,res; cin>>n>>res;
    for(int i=2;i<=n;i++){
        int x; cin>>x;
        res^=x;
    }
    if(res) cout<<"Yes"<<endl;
    else cout<<"No"<<endl;
}
signed main(){
    int t; cin>>t; while(t--) solve();
}

 P8606 [蓝桥杯 2013 国 B] 高僧斗法 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

转化为 $nim$ 模型,两个和尚的举例为石头堆高度,接下来枚举即可

#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int N=2e5+10;
int n=1,a[N],res,c[N];
bool check(){
    int sum=0;
    for(int i=1;i<=n;i+=2) sum^=c[i];
    if(sum==0) return true;
    else return false;
}
signed main(){
    while(cin>>a[n]) n++;
    for(int i=1;i<n;i++) c[i]=a[i+1]-a[i]-1;
    n--;
    if(check()) return cout<<-1,0;
    for(int i=1;i<n;i++){
        for(int j=1;j<a[i+1]-a[i];j++){
            c[i]-=j;//进行转移
            if(i!=1) c[i-1]+=j;//如果不是第一位和尚,那么i-1位和尚与i的距离增加
            if(check()) return cout<<a[i]<<' '<<a[i]+j,0;
            c[i]+=j;//回溯
            if(i!=1) c[i-1]-=j;
        }
    }
}

 

posted @ 2024-01-29 17:46  o-Sakurajimamai-o  阅读(31)  评论(0)    收藏  举报
-- --