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

原题: http://acm.hdu.edu.cn/showproblem.php?pid=5973

题意:

两个石子堆,可以在一堆里面取任意数量的石子,或者两堆中取相同数量。最后一个取完的获胜。

解析:

就是威佐夫博奕,当 m i n ( a , b ) = ( 1 + 5 ) ( ∣ a − b ∣ ) 2 ( 向 下 取 整 ) min(a,b)=\dfrac{(1+\sqrt{5})(|a-b|)}{2}(向下取整) min(a,b)=2(1+5 )(ab)时,就是必败态。

问题是此题 a , b ∈ [ 1 , 1 0 100 ] a,b\in [1,10^{100}] a,b[1,10100],需要考虑的有:

  • 大数的存储
  • 使5开根号后获得至少100位的精度
  • 大数之间的运算

所以就只好交给Java中的BigDecimal了。

BigDecimal没有sqrt函数,只能自己二分写一个,中间还需要一个 1 e − 100 1e-100 1e100 E P S EPS EPS。由于BigDecimal时间复杂度较高,所以能预处理的都要先预处理,不然直接TLE了。

代码:

import java.math.*;
import java.math.BigDecimal;
import java.util.*;

public class Main {
	public static BigDecimal EPS;
	public static BigDecimal TEN=new BigDecimal(10);
	public static BigDecimal TWO=new BigDecimal(2);
	public static BigDecimal ONE=new BigDecimal(1);
	public static BigDecimal NUM;
	
	public static BigDecimal SQRT(BigDecimal num) {
		BigDecimal l=new BigDecimal(1);
		BigDecimal r=num;

		while(r.subtract(l).compareTo(EPS)>0) {
			BigDecimal mid=l.add(r).divide(TWO);
			if(mid.multiply(mid).compareTo(num)>0) {
				r=mid;
			}
			else {
				l=mid;
			}
		}
		return l;
    }
	
    public static void main(String args[]) {
    	EPS= new BigDecimal(1);
		for(int i=1;i<=120;i++) {
			EPS=EPS.divide(TEN);
		}
		NUM=new BigDecimal(5);
   		NUM=SQRT(NUM);
   		NUM=NUM.add(ONE);
   		NUM=NUM.divide(ONE.add(ONE));
		
        Scanner cin=new Scanner(System.in);

        while(cin.hasNext()){
       		BigDecimal n,m,ma,mi;
       		n=cin.nextBigDecimal();
       		m=cin.nextBigDecimal();
       		
       		if(n.compareTo(m)>0){
       			ma=n;mi=m;
       		}
       		else{
       			ma=m;mi=n;
       		}
       		BigDecimal k=ma.subtract(mi).multiply(NUM).setScale( 0, BigDecimal.ROUND_DOWN );

       		if(mi.compareTo(k)==0){
       			System.out.println("0");
       		}
       		else{
       			System.out.println("1");
       		}
       	}
    }
}

你可能感兴趣的:(C/C++/Java/Html)