2017CCPC 秦皇岛 G

探讨了将一个数n分为m个数的和,使这些数或运算的结果最小的算法实现。通过确定最高位并尽可能均匀分配数值,使用大数模拟确保准确性。

给一个数n,要把这个数分成m个数,这m个数的和n,且要求或起来的答案最小。

因为要或,所以易知m个数中最高位最小且尽量均分即可。

均分的时候先确定一个最高位,然后从最高位向低位填数字,如果一位能填则尽量填满即可。

chawa大数模拟一哈就好了。

 

 

 

 

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

public class G{
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int t;BigInteger one,two,zero;
        one = BigInteger.valueOf(1);two = BigInteger.valueOf(2);zero = BigInteger.valueOf(0);
        t=cin.nextInt();
        //System.out.println(t);
        for(int p=1;p<=t;p++){
            BigInteger n,m,ans;
            ans=BigInteger.valueOf(0);
            n=cin.nextBigInteger();m=cin.nextBigInteger();
            //System.out.println(n);
            BigInteger tmp = new BigInteger("1");
            while((tmp.subtract(one)).multiply(m).compareTo(n)<0){
                tmp=tmp.multiply(two);
            }
            while(n.compareTo(zero)>0){
                while((tmp.subtract(one)).multiply(m).compareTo(n)>=0){
                    tmp=tmp.divide(two);
                }
                ans=ans.add(tmp);
                if(tmp.multiply(m).compareTo(n)<0){
                    n=n.subtract(tmp.multiply(m));
                }
                else{
                    n=n.mod(tmp);
                }
            }
            System.out.println(ans);
        }
    }
}
View Code

 

转载于:https://www.cnblogs.com/LMissher/p/9634303.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值