• 51nod 1185 威佐夫博奕


      有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

    【转】ACM博弈知识汇总



      这种情况下是颇为复杂的。我们用(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,奇异局势有如下三条性质:

          1。任何自然数都包含在一个且仅有一个奇异局势中。由于ak是未在前面出现过的最小自然数,所以有ak > ak-1 ,而 bk= ak + k > ak-1 + k-1 = bk-1 > ak-1 。

    所以性质1。成立。
          2。任意操作都可将奇异局势变为非奇异局势。事实上,若只改变奇异局势(ak,bk)的某一个分量,那么另一个分量不可能在其他奇异局势中,所以必然

    是非奇异局势。如果使(ak,bk)的两个分量同时减少,则由于其差不变,且不可能是其他奇异局势的差,因此也是非奇异局势。
          3。采用适当的方法,可以将非奇异局势变为奇异局势。

          假设面对的局势是(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),怎样判断它是不是

    奇异局势呢?我们有如下公式:

          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,bj+1 = aj+1+ j + 1,

    若都不是,那么就不是奇异局势。然后再按照上述法则进行,一定会遇到奇异局势。

     

     

     

    这个题目数据很大,需要用到乘法模拟。

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #define ll long long
     5 using namespace std;
     6 const  ll Gold[3] = { 618033988, 749894848, 204586834};
     7 const int mod = 1000000000;
     8 int main(){
     9     int t;
    10     scanf("%d",&t);
    11     while(t--){
    12         ll a, b;
    13         cin>>a>>b;
    14         if(a < b)swap(a,b);
    15         ll dist = a-b;
    16         ll pre = dist/mod, las = dist%mod;
    17         ll a1 = las*Gold[2];
    18         ll a2 = pre*Gold[2] + las*Gold[1] + a1/mod;
    19         ll a3 = pre*Gold[1] + las*Gold[0] + a2/mod;
    20         ll a4 = dist + pre*Gold[0] + a3/mod;
    21         cout << (a4==b?'B':'A') << endl;
    22     }
    23     return 0;
    24 }
  • 相关阅读:
    testNG参数传递方式
    TestNG超详细教程
    testNG中@Factory详解
    【转】HashMap的工作原理
    shell脚本学习笔记
    awk文本处理知识汇总
    sed文本处理知识点整理
    oracle数据库sql的基本使用
    【转】Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例
    HTML5 indexedDB数据库的入门学习(二)
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/7219552.html
Copyright © 2020-2023  润新知