1. 程式人生 > >HDU - 5973 Game of Taking Stones (威佐夫博弈 高精度)

HDU - 5973 Game of Taking Stones (威佐夫博弈 高精度)

-a span side 模板 multi amount 公式 native str

題目描述:

Two people face two piles of stones and make a game. They take turns to take stones. As game rules, there are two different methods of taking stones: One scheme is that you can take any number of stones in any one pile while the alternative is to take the same amount of stones at the same time in two piles. In the end, the first person taking all the stones is winner.Now,giving the initial number of two stones, can you win this game if you are the first to take stones and both sides have taken the best strategy?

InputInput contains multiple sets of test data.Each test data occupies one line,containing two non-negative integers a andb,representing the number of two stones.a and b are not more than 10^100.OutputFor each test data,output answer on one line.1 means you are the winner,otherwise output 0.Sample Input

2 1
8 4
4 7

Sample Output

0
1
0
題目大意:兩個人抓石子,有兩堆石子,石子數量分別是a,b,每次可以從一堆中抓若幹石子,也可以從兩堆同時抓取相同數量的石子,誰先抓完誰獲勝,現在你先手,問是否必勝,必勝輸出1否則輸出0.

題解:裸的威佐夫博弈和隊友談論了半天沒看出來,神奇的是隊友竟然推出了威佐夫博弈奇異局勢的數列(0,0) (1,2) (3,5) (4,7) (6,10) (8,13) (9,15) (11,18)(12,20)……可以說她是一只可愛的小仙女了。
但算不出通項公式也算是沒轍,話說威佐夫博弈中根號5怎麽來的竟然和黃金分割數有關。

【威佐夫博弈】
威佐夫博弈:有兩堆石子,每次一個人可以兩堆同時取相同數量的石子,也可以只取其中一堆的石子,最後誰取完誰獲勝,請問先手還是後手勝?

奇異局勢:
讓先手必輸的局勢,那麽由這些局勢在規定範圍內拓展的局勢也是先手必輸的局勢(但在這裏雙方自由選取,不適用)。我們可以得出一些局勢使A必輸:(0,0) (1,2) (3,5) (4,7) (6,10) (8,13) (9,15) (11,18)(12,20)……我們稱這些局勢為奇異局勢

  對於奇異局勢來說,有以下性質:

  1. 任何自然數都一定包含在一個奇異局勢中。
  2. 任意操作都可以將奇異局勢轉變為非奇異局勢。
  3. 可以將非奇異局勢轉變為奇異局勢。

那麽,當我們面對下列情況時,可以這樣應對:

當a=b時,兩堆同時取a

當a=ak,b>bk時,2堆取b-bk個

當a=ak,b<bk時,2堆取a-a(b-a)個

當a>ak,b=bk(ak+k)時,1堆取a-ak個

當a<ak,b=bk(ak+k)時,從2堆中拿走若幹變成奇異局勢

如何判斷一個數對是不是奇異局勢呢?

當a=(下取整)k*(1+√5)/2,b=ak+k時(k為任意非負整數)局勢為奇異局勢

【威佐夫博弈高精度模板】JAVA版本

import java.math.BigInteger;
import java.util.Scanner;

import java.math.BigDecimal ;
public class Main {
    
    //對常數開方保留多位小數,返回高精度小數
    private static BigDecimal sqrt(BigDecimal x, int n) {
        BigDecimal ans = BigDecimal.ZERO;
        BigDecimal eps = BigDecimal.ONE;
        for (int i = 0; i < n; ++i) {
            while (ans.pow(2).compareTo(x) < 0) {
                ans = ans.add(eps);
            }
            ans = ans.subtract(eps);
            eps = eps.divide(BigDecimal.TEN);
        }
        return ans;
    }
    
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        while(cin.hasNext()) {
            BigDecimal a = cin.nextBigDecimal();
            BigDecimal b = cin.nextBigDecimal();
            BigDecimal c = sqrt(new BigDecimal(5), 120);
            c = c.add(BigDecimal.ONE).divide(new BigDecimal(2));
            BigDecimal t = null;
            
            if(a.compareTo(b) == 1) {
                t = a;
                a = b;
                b = t;
            }
            //計算(bk - ak ) * (1+sqrt(5))/2 == ak是否成立 左邊向下取整
            if( b.subtract(a).multiply(c).setScale(0, BigDecimal.ROUND_DOWN).equals(a)) {
                System.out.println(0);
            }
            else
                System.out.println(1);
        }
        
        cin.close();
    }
    
}

 

HDU - 5973 Game of Taking Stones (威佐夫博弈 高精度)