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

    Numbers

    Time Limit: 2 Seconds      Memory Limit: 65536 KB

    DreamGrid has a nonnegative integer n . He would like to divide n into m nonnegative integers a1,a2,...am and minimizes their bitwise or (i.e.a1+a2+...+am=n  and a1 OR a2 OR a3...OR am should be as small as possible).

    Input

    There are multiple test cases. The first line of input contains an integer , indicating the number of test cases. For each test case:

    The first line contains two integers n  and  m ( 0<=n<=1e1000 1<=m<=1e100).

    It is guaranteed that the sum of the length of does not exceed 20000

    Output

    For each test case, output an integer denoting the minimum value of their bitwise or.

    Sample Input

    5
    3 1
    3 2
    3 3
    10000 5
    1244 10

    Sample Output

    3
    3
    1
    2000
    125

    Author: LIN, Xi
    Source: The 2017 China Collegiate Programming Contest, Qinhuangdao Site

    /*
    * 题意:给你一个1e1000的数,让你分成最多1e100位,然后互相进行或运算,得到的值最小
    *
    * 思路:让高位最小然后向低位贪心,判断当前为能否为0,能为0的条件是,后面几位都是1,并且有m个,加起来如果大于当前值的话
    *   那么这位就可以为0,否则只能为1,既然为1了,那么尽量多填1,这样保证了结果最优    
    * */
    import java.math.BigInteger;
    import java.util.Scanner;
    
    public class Main {
    
        public static void main(String[] args) {
            // write your code here
            Scanner in=new Scanner(System.in);
            int t;
            BigInteger n,m,x,sum;
            BigInteger [] pre=new BigInteger[4005];//表示后缀和
            String s;
            x=new BigInteger("1");
            pre[0]=new BigInteger("0");
            for(int i=1;i<4005;i++){
                pre[i]=pre[i-1].add(x);
                x=x.multiply(new BigInteger("2"));
            }
            t=in.nextInt();
            for(int ca=0;ca<t;ca++){
                n=in.nextBigInteger();
                m=in.nextBigInteger();
                sum=n;
                int tol=0;
                while(n.compareTo(new BigInteger("0"))==1){
                    tol++;
                    n=n.divide(new BigInteger("2"));
                }
                x=new BigInteger("0");
                //判断这一位的累加和能不能用后边的所有空间放下,能的话就转移到下一位,不能的话就把这一位都填满
                for(int i=tol;i>=1;i--){//枚举每位
                    x=x.multiply(new BigInteger("2"));
                    int ok=sum.compareTo(pre[i - 1].multiply(m));
                    if ( ok<=0) {//能用剩余的空间放下
                        continue;
                    } else {//放不下
                        x = x.add(new BigInteger("1"));
                        BigInteger cur = pre[i].subtract(pre[i - 1]);
                        BigInteger cnt = sum.divide(cur);
                        if (cnt.compareTo(m) >= 0) {
                            sum = sum.subtract(cur.multiply(m));
                        } else {
                            sum = sum.subtract(cur.multiply(cnt));
                        }
                    }
                }
                System.out.println(x);
            }
        }
    }
  • 相关阅读:
    (深入理解计算机系统)内存对齐
    (深入理解计算机系统)AT&T汇编指令
    (深入理解计算机系统)编译,链接和装载
    (C)struct结构体指针
    (linux)BSP板级支持包开发理解
    TortoiseSVN使用笔记
    (linux)idr(integer ID management)机制
    (linux)struct inode 和 struct file
    cygwin使用笔记
    Zookeeper学习总结
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/7762596.html
Copyright © 2011-2022 走看看