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
3312000125
题意:
给你一个数n,要你把它分成m个数a1,a2,a3,...am(a1+a2+...+am=n),使得a1|a2|a3|a4|...|am最小
解析:
这道题就是从n的二进制最高位一步一步向低位移贪心答案,贪心的时候,因为要求是min,所以要尽可能的放0,当不得不放1的时候,就只能放1
这个不得不的条件就是这一位k:(2^k-1)*m<n,说明第k位这个位置在a1...am中一定有有一个是1,即答案的第k位为1,然后既然第k位已经有1了,那么就
那么就要多放几个,这样后面就可以少放点。那么就要求出最多有多少数第k位能放1=min(m,n/2^k),然后n减去这个数,递归处理就可以了
import java.math.*;
import java.util.*;
public class Main {
public static BigInteger n,m;
public static void solve()
{
BigInteger ck=BigInteger.ONE;
int up=0;
while(ck.compareTo(n)<=0)
{
ck=ck.shiftLeft(1);
up++;
}
ck=ck.shiftRight(1);
up--;
BigInteger ans=BigInteger.ZERO;
for (int i=up;i>=0;i--)
{
BigInteger cc=BigInteger.valueOf(2).pow(i);
BigInteger bei=n.divide(cc);
if (cc.subtract(BigInteger.ONE).multiply(m).compareTo(n)<0)
{
if(bei.compareTo(m)>=0)
{
n=n.subtract(m.multiply(cc));
ans=ans.add(cc);
}
else
{
n=n.subtract(bei.multiply(cc));
ans=ans.add(cc);
}
}
}
System.out.println(ans);
}
public static void main (String[] args)
{
Scanner sc=new Scanner(System.in);
while(sc.hasNextInt())
{
int t=sc.nextInt();
for (int k=0;k<t;k++)
{
n=sc.nextBigInteger();
m=sc.nextBigInteger();
solve();
}
}
}
}
python:
while(True):
try:
t=int(input())
for k in range(0,t):
n,m=raw_input().strip().split() #strip将收尾的空格符,换行符去掉
n=int(n) #split 将字符串按空字符(空格、换行(\n)、制表符(\t))分离成独立的字符串放入列表
m=int(m)
c=1
while(c<=n):
c<<=1
c>>=1
ans=0
while(c>0):
if (c-1)*m < n:
if(n//c>=m):
n-=m*c
ans+=c
else:
n-=n//c*c
ans+=c
#print('n:'+repr(n)+'c:'+repr(c)+'flag:'+repr(flag)+'ans:'+repr(ans))
c=c>>1
#print('c'+repr(c))
print(ans)
except:
break