[博弈论]博弈混合

版权声明:虽然博主很菜,但是还是请注明出处(我觉得应该没人偷我的博客) https://blog.csdn.net/qq_43346903/article/details/87895794

给你一个n∗m的棋盘,然后给你4种棋子,分别是:
1.王:能横着走,或者竖着走,或者斜着走,每次可以走1格
2.车:可以横着走或者竖着走,每次可以走无数格
3.马:走日字形,例如:如果现在在(1,1),可以走到(2,3),即先走一格直线,然后斜着走一格
4.王后:可以横着走,或者竖着走,或者斜着走,每次可以走无数格 所有棋子在走的时候只能向右或向下走,不可后退,谁先走到(n,m)点,谁赢.

王就是把必胜必败写出来发现只和两堆的奇偶性有关
车就是两堆石子谁先取完,异或起来
马的话手推一下发现只有当3|(n+m-2)时有胜负,如果两堆差值为1那么先手胜,相等先手负
后就是威佐夫博弈

Code:

#include<bits/stdc++.h>
using namespace std;
int main(){
 int t;
 int n,m;
 int k;
 cin>>t;
 while(t--){
  cin>>k>>n>>m;
  if(n>m) swap(n,m);
  --n,--m;
  switch(k){
   case 1:{
    if(n%2==0 && m%2==0) puts("N");
    else puts("Y");
    break;
   }
   case 2:{
    if((n^m)==0) puts("N");
    else puts("Y");
    break;
   }
   case 3:{
    ++n,++m;
    if(((n+m-2))%3) puts("D");
    else{
     int r=(2*m-n-1)/3,d=(2*n-m-1)/3;
                 if(abs(r-d)>=2) printf("D\n");
                 else if(abs(r-d)==1) printf("Y\n");
                 else printf("N\n");
    }
    break;
   }
   default:{
    int k=m-n;
    m=(int)(k*(1+sqrt(5))/2.0);
    if(m==n) puts("N");
    else puts("Y");
   }
  } 
 }
 return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43346903/article/details/87895794