標籤:big java print tin bsp stat cas 二進位 rgs
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3987
題意:
給出一個數n,現在要將它分為m個數,這m個數相加起來必須等於n,並且要使得這m個數的或值最小。
思路:
從二進位的角度分析,如果這m個數中有一個數某一位為1,那麼最後或起來這一位肯定是為1的,所以如果某一位為1了,那麼我們盡量就讓其餘位也等於1。
所以我們從最高位開始枚舉,看看這一位是否需要為1,如果需要為1的話,那麼剩下的幾個數也盡量讓這一位等於1。
1 import java.math.*; 2 import java.util.Scanner; 3 4 public class Main { 5 public static void main(String[] args) { 6 BigInteger n, m; 7 Scanner in = new Scanner(System.in); 8 int T = in.nextInt(); 9 for(int cas=0;cas<T;cas++){10 n = in.nextBigInteger();11 m = in.nextBigInteger();12 int len = 0;13 BigInteger ss = n;14 while(ss.compareTo(BigInteger.ZERO)>0){15 ss = ss.divide(BigInteger.valueOf(2));16 len++;17 }18 BigInteger tmp;19 BigInteger ans = new BigInteger("0");20 for(int i = len; i>0; i--){21 if(n.compareTo(BigInteger.ZERO)<=0) break;22 tmp = BigInteger.valueOf(2).pow(i-1).subtract(BigInteger.valueOf(1));23 BigInteger sum = tmp.multiply(m);24 if(sum.compareTo(n)<0){25 BigInteger num = n.divide(BigInteger.valueOf(2).pow(i-1));26 if(num.compareTo(m)>0) num = m;27 n = n.subtract(BigInteger.valueOf(2).pow(i-1).multiply(num));28 ans = ans.add(BigInteger.valueOf(2).pow(i-1));29 }30 }31 System.out.println(ans);32 }33 in.close();34 }35 }
ZOJ 3987 Numbers(Java枚舉)