zoukankan      html  css  js  c++  java
  • 2017CCPC 秦皇岛 G. Numbers (贪心 + java大数)

    题意:
    一个数n,分成m个数a1...am (n,m很大),使a1 OR a2 OR ... OR an的值最小,输出这个最小值。
    思路:

    • 首先有一个OR的性质:多个数OR,如果一个数二进制某一位是1, 最后答案这一位一定是1。那么要让结果最小,肯定每个数二进制最高的1位要小。
    • 第二:答案是个OR的最小值,那么说明答案中的最高位的1不能再减小了,(如果可以降位那就不是最小的答案了),那么这一点感性认识上可能存在方法去构造最小的答案。
    • 怎么理解呢?至少能通过方法找到最高位1的位置。那么这个题贪心的思路就有了。如果处理第i位时,m个数0 ~ i-1位全是1也不能凑出剩下的n,那第i位必然是1.由于第i位确定是1,那一定要尽可能多的让第i位是1(反正最后答案这一位都已经是1了,多一些位是1结果都一样).这样我们就能确定每一位是否是1.那就构造出答案了。
    • 这题值得多想想。
    //c++写的话大致思路
    int n;
    int len = //n二进制位数
        
    for(int i = len - 1; i >= 0 && n > 0; -- i){
        int tmp = 1 << i;
        temp = (tmp - 1) * m;
        if(temp < n){
            n = n - tmp * min(m, n / tmp);
            ans = ans | tmp;
        }
    }
        cout<< ans <<endl;
    
    import java.io.*;
    import java.math.*;
    import java.util.Scanner;
    
    
    public class Main {
    	
    	static BigInteger n, m;
    	
    	public static void solve() {
    		int len = 0;
    		BigInteger zero = BigInteger.ZERO;
    		BigInteger res = zero;
    		
    		len = n.bitLength();
    		for(int i = len - 1; i >= 0 && n.compareTo(zero) > 0; i --) {
    			BigInteger tmp = BigInteger.ONE.shiftLeft(i);
    			BigInteger temp = (tmp.subtract(BigInteger.ONE)).multiply(m);
    			if(temp.compareTo(n) < 0) {
    				n = n.subtract(tmp.multiply(m.min(n.divide(tmp))));
    				res = res.or(tmp);
    			}
    		}
    		System.out.println(res);
    	}
    	
    	public static void main(String[] args) {
    		Scanner cin = new Scanner(System.in);
    		int T; T = cin.nextInt();
    		while(T -- > 0) {
    			n = cin.nextBigInteger();
    			m = cin.nextBigInteger();
    			solve();
    		}
    	}
    }
    
    
  • 相关阅读:
    用Jquery控制文本框只能输入数字和字母
    Math:弧度制
    python学习之案例
    python自动化模块之实践一
    python学习之路 第六天
    python学习之路 第五天
    python学习之路 第四天
    python学习之路 第三天
    python学习之路 第二天
    python学习之路 第一天
  • 原文地址:https://www.cnblogs.com/A-sc/p/13786967.html
Copyright © 2011-2022 走看看