zoj3987 Numbers(大数+贪心)

版权声明:本文为博主原创文章,转载请说明出处。 https://blog.csdn.net/xianpingping/article/details/83386972

Numbers


Time Limit: 2 Seconds      Memory Limit: 65536 KB


DreamGrid has a nonnegative integer . He would like to divide into nonnegative integers and minimizes their bitwise or (i.e. and 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 and ().

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

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

题意:给你一个1e1000的数,让你分成最多1e100位,然后互相进行或运算,得到的值最小

思路:

让高位最小然后向低位贪心,判断当前为能否为0,能为0的条件是,后面几位都是1,并且有m个,加起来如果大于当前值的话 那么这位就可以为0,否则只能为1,既然为1了,那么尽量多填1,这样保证了结果最优

开始没有用pre预处理二进制位,结果超时了。pow在大数中简直不能用。

感受:

反正比赛时我没有推出来。欸。跑偏了。

代码:

pre【i】代表1<<i.

import java.math.BigInteger;
import java.util.Scanner;


public class lalala {
	
	public static void main(String[] args) {
		BigInteger a,b;
		BigInteger tmp,tmp2,tmp3,ans;
		int tol;///代表最多几位
		Scanner sc=new Scanner(System.in);
		int t=sc.nextInt();
		BigInteger pre[]=new BigInteger[7000];
		BigInteger pp=new BigInteger("1");
		for(int i=0;i<=6666;i++){
			pre[i]=pp;
			pp=pp.multiply(new BigInteger("2"));
		}
		while(t!=0){
		t--;
		a=sc.nextBigInteger();
		b=sc.nextBigInteger();
		tmp=a.divide(new BigInteger("2"));
		///tol=tmp.intValue();
		tol=0;
		BigInteger n=a;
        while(n.compareTo(new BigInteger("0"))==1){
            tol++;
            n=n.divide(new BigInteger("2"));
        }
	
		BigInteger sum=new BigInteger("0");
		BigInteger er=new BigInteger("2");
		ans=new BigInteger("0");
		for(;tol>=0;tol--){
			///当前位放0;
			tmp=b.multiply(pre[tol].subtract(new BigInteger("1")));///tmp=b*(pow(2,tol)-1)...就是假设后边所有放1.
			tmp3=a.divide(pre[tol]);///tmp3=a/pow(2,tol);看当前最多能放几个1,能放几个放几个
			if(tmp3.compareTo(b)>0){///如果超过了b个,说明全放
				tmp3=b;
			}
			tmp3=tmp3.multiply(pre[tol]);
			tmp2=sum.add(tmp);///sum+tmp;
			if(tmp2.compareTo(a)<0 ){///说明当前位置必须放1.而且b个数字全放1
				a=a.subtract(tmp3);
				ans=ans.add(pre[tol]);
			}
		}
		System.out.println(ans);
		}
	}

}

猜你喜欢

转载自blog.csdn.net/xianpingping/article/details/83386972