三种常见博弈(同余 异或 黄金分割率)

一 同余博弈(Bash)

有一堆石子共有N个。A B两个人轮流拿,A先拿。每次最少拿1颗,最多拿K颗,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N和K,问最后谁能赢得比赛。

 

  A先走,只要保证每一个回合拿的总数都是k+1,就能保证B获胜。所以只要求出总数对k+1的取余是否为0就行

  

#include<bits/stdc++.h>
using namespace std;
int main(){
  int n,a,b;
  cin>>n;
  while(n--){
    cin>>a>>b;
    if(a%(b+1)==0)
      cout<<'B'<<endl;
    else
      cout<<'A'<<endl;
  }

  return 0;

}

 

 

二 异或博弈(Nim)

有N堆石子。A B两个人轮流拿,A先拿。每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N及每堆石子的数量,问最后谁能赢得比赛。

例子:3堆石子,每堆1颗。A拿1颗,B拿1颗,此时还剩1堆,所以A可以拿到最后1颗石子。

  

  拿两堆石子举例,如果石子不等,那么第一个人必定能构造 n n的情况, 那么无论第二个人拿多少,第一个人下一次仍然保持n n 就一定能胜利。

    如果石子相等, 那么第一个人必定破坏n n 的情况 ,第二个人只要反过来重新构造N N 第二个人就会胜利

       面对奇异局势,面对者必败。

  如果三堆石子:   若有两堆相等一堆不等,那么则在上述情况中胜负情况发生转变。

  结论:

    如果这些石子不能构成奇异局势  也就是 两两相同那么B必败。

    否则B就可以构造奇异局势 N N 让A面对。A必败

  

#include<bits/stdc++.h>
using namespace std;
int a[1050];
int main(){
int n,t,ans=0;
cin>>n;
while(n--){
  cin>>t;
  ans^=t;//异或运算
  }
  if(ans==0)
    cout<<'B'<<endl;
  else
    cout<<'A'<<endl;
  return 0;
}

 

 

三 黄金分割率博弈(威佐夫博弈)

有2堆石子。A B两个人轮流拿,A先拿。每次可以从一堆中取任意个或从2堆中取相同数量的石子,但不可不取。拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出2堆石子的数量,问最后谁能赢得比赛。
 
例如:2堆石子分别为3颗和5颗。那么不论A怎样拿,B都有对应的方法拿到最后1颗。
 
  只要保证(b-a)*(sqrt(5)+1)/2==a,B一定能赢。(sqrt(5)+1)/2是黄金分割率等于0.618.
  

#include<bits/stdc++.h>
using namespace std;
int main(){
int t,n,m,temp;
cin>>t;
while(t--){
  cin>>n>>m;
  if(n>m)
    swap(n,m);
  temp=(m-n)*(sqrt(5)+1)/2;
  if(n==temp)
    cout<<'B'<<endl;
  else
    cout<<'A'<<endl;
  }
  return 0;
}

 

原文链接: https://www.cnblogs.com/xly1029/p/9157539.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    三种常见博弈(同余 异或 黄金分割率)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/275565

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月15日 上午1:06
下一篇 2023年2月15日 上午1:07

相关推荐