1. 程式人生 > >ZOJ 3987 Numbers (貪心+JAVA大數)

ZOJ 3987 Numbers (貪心+JAVA大數)

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

題意:

給你兩個大數n,m,讓你把n分成m個數的和,求這m個數的最小或值。

容易想到先平分成n/m,然後在儘可能不增加最高位的情況下新增餘數。

這樣最高位就確定了。

然後這個數不會超過2的5000次方。(其實4000次方就夠了)

直接從最高位依次列舉,看看m個數的這一位能不能全為0即可。

程式碼:(第一個正式賽模擬賽上AC的java程式碼,鼓掌!!!下週還得考試。。。)

import java.math.*;
import java.util.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
	public static BigInteger poww(BigInteger n,BigInteger m) {
        BigInteger bigN = n;
        BigInteger bigM = m;
        BigInteger result = BigInteger.ONE;
        for (BigInteger i = BigInteger.ONE; i.compareTo(bigM) <= 0; i = i.add(BigInteger.ONE)) {
            result = result.multiply(bigN);
        }
        return result;
	}
	public static void main(String[] args) {
	Scanner sc = new Scanner(System.in);
	//result.toString();
	int T,cas=1;
	BigInteger n=new BigInteger("1");
	BigInteger m=new BigInteger("1");
	BigInteger k=new BigInteger("1");
	BigInteger x=new BigInteger("1");
	BigInteger y=new BigInteger("1");
	BigInteger[] tmp=new BigInteger[5010];
	BigInteger two=new BigInteger("2");
	BigInteger one=new BigInteger("1");
	BigInteger zero=new BigInteger("0");
	BigInteger ans=new BigInteger("0");
	tmp[0]=one;
	for(int i=1;i<5010;i++)
	tmp[i]=tmp[i-1].multiply(two);
	T=sc.nextInt();
	int cnt;
	while(T>0)
	{
		T--;
		n=sc.nextBigInteger();
		m=sc.nextBigInteger();
		x=n.divide(m);
		y=n.mod(m);
		cnt=0;ans=zero;
		while(tmp[cnt].compareTo(x)<0||(tmp[cnt].equals(x)&&zero.compareTo(y)<0))
		{
			cnt++;
		}
		BigInteger a=tmp[cnt].subtract(one);
		if(zero.compareTo(y)<0&&a.equals(x)) cnt++;
		//System.out.println("  *    "+cnt);
		for(int i=cnt;i>=0;i=i-1)
		{
			a=tmp[i].multiply(m).subtract(m);
			if(a.compareTo(n)<0) {
			a=tmp[i].multiply(m);
			if(n.compareTo(a)<0)
			{
				a=n.divide(tmp[i]);
				if(a.equals(zero)) continue;
				a=tmp[i].multiply(a);
				n=n.subtract(a);
				ans=ans.add(tmp[i]);
				continue;
			}
			else
			{
				ans=ans.add(tmp[i]);
				n=n.subtract(a);
				if(n.equals(zero)) break;
			}
			}
		}
		System.out.println(ans.toString());
	}
	}
}