2017CCPC秦皇岛 G题Numbers&&ZOJ3987【大数】

题意:

 给出一个数n,现在要将它分为m个数,这m个数相加起来必须等于n,并且要使得这m个数的或值最小。

思路:

从二进制的角度分析,如果这m个数中有一个数某一位为1,那么最后或起来这一位肯定是为1的,所以如果某一位为1了,那么我们尽量就让其余位也等于1。所以我们从最高位开始枚举,看看这一位是否需要为1,如果需要为1的话,那么剩下的几个数也尽量让这一位等于1。

代码:

不懂啊,还是看别人的代码写的,觉得有用就拿去吧。(卧槽,第一次开我的IDEA写java还不错的嘛)

import java.math.*;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        BigInteger n, m;
        Scanner in = new Scanner(System.in);
        int T = in.nextInt();
        for(int cas=0;cas<T;cas++){
            n = in.nextBigInteger();
            m = in.nextBigInteger();
            int len = 0;
            BigInteger ss = n;
            while(ss.compareTo(BigInteger.ZERO)>0){
                ss = ss.divide(BigInteger.valueOf(2));
                len++;
            }
            BigInteger tmp;
            BigInteger ans = new BigInteger("0");
            for(int i = len; i>0; i--){
                if(n.compareTo(BigInteger.ZERO)<=0)  break;
                tmp = BigInteger.valueOf(2).pow(i-1).subtract(BigInteger.valueOf(1));
                BigInteger sum = tmp.multiply(m);
                if(sum.compareTo(n)<0){
                    BigInteger num = n.divide(BigInteger.valueOf(2).pow(i-1));
                    if(num.compareTo(m)>0)  num = m;
                    n = n.subtract(BigInteger.valueOf(2).pow(i-1).multiply(num));
                    ans = ans.add(BigInteger.valueOf(2).pow(i-1));
                }
            }
            System.out.println(ans);
        }
        in.close();
    }
}
posted @ 2017-11-02 11:11  codeg  阅读(288)  评论(0编辑  收藏  举报