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