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

题目描述:

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();
    }

}
 

原文地址:https://www.cnblogs.com/czsharecode/p/9595399.html

时间: 2024-10-10 06:57:22

HDU - 5973 Game of Taking Stones (威佐夫博弈 高精度)的相关文章

HDU 1527 取石子游戏(威佐夫博弈)

取石子游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8514    Accepted Submission(s): 4837 Problem Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的

HDU 1527 取石子游戏 威佐夫博弈

题目来源:HDU 1527 取石子游戏 题意:中文 思路:威佐夫博弈 必败态为 (a,b ) ai + i = bi     ai = i*(1+sqrt(5.0)+1)/2   这题就求出i然后带人i和i+1判断是否成立 以下转自网上某总结 有公式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,可以先

hdu 1527 取石子游戏(威佐夫博奕模板题)

取石子游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3562    Accepted Submission(s): 1789 Problem Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的

HDU 2177 取(2堆)石子游戏 威佐夫博弈

题目来源:HDU 2177 取(2堆)石子游戏 题意:中文 思路:判断是否是必败态就不说了 做过hdu1527就知道了 现在如果不是必败态 输出下一步所有的必败态 题目要求先输出两堆都取的方案 首先 a = b 直接2堆取完 a != b 因为bi = ai+i 现在知道ak 和 bk 那么 k = bk-ak 得到k 求出 aj 和 bj 如果ak-aj == bk-bj && ak-aj > 0(aj, bj)是必败态 输出aj bj 然后是只取一堆的情况 假设a不变 求出对应的

HDU 2177——威佐夫博弈

题目: Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后把石子全部取完者为胜者.现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者.如果你胜,你第1次怎样取子? Input 输入包含若干行,表示若干种石子的初始情况,其中每一行包含两个非负整数a和b,表示两堆石子的数目,a和b都不大于1,000,000,

HDU 2177 —— (威佐夫博弈)

威佐夫博弈奇异态(必败态)的条件是a[k]=[k*(sqrt(5.0)+1.0)/2.0].暴力找出必败态即可. 代码如下: 1 #include <stdio.h> 2 #include <algorithm> 3 #include <math.h> 4 #include <vector> 5 #include <map> 6 #include <set> 7 using namespace std; 8 typedef pair&

取(2堆)石子游戏(威佐夫博弈+hdu2177)

T - 取(2堆)石子游戏 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 2177 Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后把石子全部取完者为胜者.现在给出初始的两堆石子的数目,

3.威佐夫博弈

先上一串数吧,, (0,0).(1,2).(3,5).(4,7).(6,10).(8,13).(9,15).(11,18).(12,20). 大家发现规律啦吗? 没发现也不要紧,我来给大家说一下其中的奥妙吧,哈哈哈. 咱们先不说(0,0),从第二个开始说,她是以1开始的,而2比1多1,第三个是从3开始的,接着5比3多2,第4个事从4开始的,7比4多3...每一个数对的两个数之间都是从1开始相差2,3,4...再观察每个数对的第一个数,他们都是前面的那些数对中没有出现过的数的最小自然数,因此,稍稍

HDU5973 Game of Geting Stone(威佐夫博弈)

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 tak