• ZOJ


    参考自:https://blog.csdn.net/u013534123/article/details/78484494

    题意:

    给出两个数字n,m,把n分成m份,使得以下最小

    思路:

    或运算只有0|0=0,如果这一位有一个1,那么结果中这一位一定是1,所以我们要尽可能把1集中在几个位上(以二进制看结果)

    (二进制)主要的思想是把高位设置成1,这样可以分担大部分数值

    用 i-1 位全部为1的二进制数t × m 与n进行判断

    如果n大,说明n可以分成 pow(2,i)*m+x,x为不确定数字,这样说明把m个数字第i为设置为1

    如果n小,说明分不出来,继续使i变小判断

    代码:

    import java.util.*;
    import java.io.*;
    import java.math.*;
    
    public class Main {
    
        public static BigInteger two = BigInteger.valueOf(2);
        public static BigInteger p[] = new BigInteger[5000];
    
        public static void init()                    //预处理二进制下每一位都为1的值
        {
            p[1] = BigInteger.ONE;
            p[0] = BigInteger.ZERO;
            for (int i = 2; i < 5000; i++)
                p[i] = p[i - 1].multiply(two);
            for (int i = 2; i < 5000; i++)
                p[i] = p[i].add(p[i - 1]);            //p[i]不仅是二进制i位为1,还记录了加和
        }
    
        public static void main(String[] args) {
            init();
            Scanner cin = new Scanner(System.in);
            int T = cin.nextInt();
            for (int ca = 1; ca <= T; ca++) {
                BigInteger ans = BigInteger.ZERO;
                BigInteger a = cin.nextBigInteger();
                BigInteger b = cin.nextBigInteger();
                int up = 0;
                for (int i = 0; i < 5000; i++)                        //首先找到最高位
                    if (p[i].compareTo(a) > 0) {                      //找到第一个比a大的数
                        up = i;
                        break;
                    }
                for (int i = up; i >= 1; i--) {
                    ans = ans.multiply(two);                                //还原二进制为十进制
                    if (a.compareTo(p[i - 1].multiply(b)) <= 0) continue;    //若后面可以大于n剩余的量,那么这一位放0
                    BigInteger now = p[i].subtract(p[i - 1]);            //否则就只能放1,而且要让n尽量减去更多,剩下更少
                    BigInteger k = a.divide(now);
                    ans = ans.add(BigInteger.ONE);
                    if (k.compareTo(b) > 0) a = a.subtract(now.multiply(b));
                    else a = a.subtract(now.multiply(k));
                }
                System.out.println(ans);
            }
        }
    }
    
    
  • 相关阅读:
    easyui里弹窗的两种表现形式
    如何获得 request, "request.getSession(true).setAttribute("a",a);"与“request.setAttribute("a",a);”区别
    JSTL和EL的区别
    windows下安装多个tomcat服务
    谷歌浏览器控制台使用
    递归和迭代有什么区别?
    left join ,right join ,inner join ,cross join 区别
    sql良好习惯
    添加了一个字段,查询速度突然变慢
    热点账户问题-转
  • 原文地址:https://www.cnblogs.com/somliy/p/9739785.html
Copyright © 2020-2023  润新知