51Nod 1072 - 威佐夫游戏(博弈)

来源:互联网 发布:photoshop软件介绍 编辑:程序博客网 时间:2024/06/06 21:23

1072 威佐夫游戏
基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注
有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。
Input示例
3
3 5
3 4
1 9
Output示例
B
A
A

解题思路:
我们用(ak,bk)(ak ≤ bk ,k=0,1,2,…,n)表示两堆物品的数量并称其为局势,如果甲面对(0,0),那么甲已经输了,这种局势我们称为奇异局势。前几个奇异局势是:(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20)。
可以看出,a0=b0=0,ak是未在前面出现过的最小自然数,而 bk= ak + k。

ak =[k(1+√5)/2],bk= ak + k (k=0,1,2,…n 方括号表示取整函数)
奇妙的是其中出现了黄金分割数(1+√5)/2 = 1.618…因此,由ak,bk组成的矩形近似为黄金矩形,由于2/(1+√5)=(√5-1)/2,可以先求出j=[a(√5-1)/2],若a=[j(1+√5)/2],那么a = aj,bj = aj + j,若不等于,那么a = aj+1,b = aj + j + 1,若都不是,那么就不是奇异局势。然后再按照上述法则进行,一定会遇到奇异局势。

AC代码:

#include<stdio.h>#include<algorithm>#include<math.h>using namespace std;int main(){    double tmp = (sqrt(5.0)+1)/2;    int loop;    scanf("%d",&loop);    while(loop--)    {        int a;        int b;        scanf("%d%d",&a,&b);        if(a > b)   swap(a,b);        b -= a;        if(a == (int)(b*tmp))   printf("B\n");        else                    printf("A\n");    }    return 0;}
0 0