博弈论
尼姆($nim$)游戏:
P2197 【模板】Nim 游戏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
对于博弈论游戏,如果当前的选手具有控制权的话,那么当前选手是必赢的,也就是当前选手做出的这步选择后,之后的局面都是在其预料之中的,换句话说,先掌握了控制权即赢. 考虑什么情况下是控制权,对于一个局面,我们最终的局面一定是 0 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; } } }

浙公网安备 33010602011771号