威佐夫博弈 有2堆石子。A B两个人轮流拿,A先拿。

有2堆石子。A B两个人轮流拿,A先拿。每次可以从一堆中取任意个或从2堆中取相同数量的石子,但不可不取。拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出2堆石子的数量,问最后谁能赢得比赛。

例如:2堆石子分别为3颗和5颗。那么不论A怎样拿,B都有对应的方法拿到最后1颗。

Input

第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000) 第2 - T + 1行:每行2个数分别是2堆石子的数量,中间用空格分隔。(1 <= N <= 2000000)

Output

共T行,如果A获胜输出A,如果B获胜输出B。

Sample Input

3
3 5
3 4
1 9

Sample Output

B
A
A

 

首先我们引入奇异局势(也就是必败局势,我实在是很不明白,为什么好好的名词非要按字面翻译成各种令人费解的名字)的概念:可以知道,(0,0)一定是一个奇异局势,以此类推(0,i),(i,i),(i,0)就一定是必胜局势。因必胜局势的上一步便是奇异局势,故我们可以得到奇异局势如下:(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20)……

可以发现(我没发现),奇异局势(ak,bk)是这样构成的:(ak,ak+k),ak是在前面未出现过的最小自然数。

奇异局势有以下三条性质:

任何自然数都包含在唯一一个奇异局势之中。
任意操作都可将奇异局势变为非奇异局势。
方法适当,非奇异局势可以变为奇异局势。
假设面对的局势是(a,b),若 b = a,则同时从两堆中取走 a 个物体,就变为了奇异局势(0,0);

如果a = ak ,b > bk,那么,取走b  – bk个物体,即变为奇异局势;

如果 a = ak ,  b < bk ,则同时从两堆中拿走 ak – ab + ak个物体,变为奇异局势( ab – ak , ab – ak+ b – ak);

如果a > ak ,b= ak + k,则从第一堆中拿走多余的数量a – ak 即可;如果a < ak ,b= ak + k,分两种情况,第一种,a=aj (j < k),从第二堆里面拿走 b – bj 即可;第二种,a=bj (j < k),从第二堆里面拿走 b – aj 即可。

以上关于非奇异到奇异的拿法是我粘的,总之,判断(a,b)是否为奇异矩阵的公式如下:,如果成立,则此局面为奇异局势,先手必败。
题解内容
原文链接:https://blog.csdn.net/weixin_41934068/article/details/81673696

#include
#include
int main()
{
    int t,n,m,temp;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        if(n>m)
        {
            int k=n;
            n=m;
            m=k;
        }
        temp=(m-n)*(sqrt(5)+1)/2;
        if(n==temp)
            printf("B\n");
        else
            printf("A\n");
    }
    return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(威佐夫博弈 有2堆石子。A B两个人轮流拿,A先拿。)