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());
}
}
}

本文介绍了一种解决将大整数n分割成m个非负整数之和,以求这些整数的最小或值的问题的算法。通过合理分配余数和枚举最高位,确保了分割后的整数或值最小化。
568

被折叠的 条评论
为什么被折叠?



