题目链接走~~~~~
这次不能甩锅了呜呜呜。
先讲一下题意,就是给你一个数分成m组,使他们的或最小。
分析:
一开始想太简单了,有点先入为主的意思,虽然想到了,均分二进制位会使或值最小,但是当无法恰好均分时,无法处理了
。。。自闭
接下来是重点了呢:
我们可以不断的按位来分,
首先,我们要找到他的最高位,如果(2 * k - 1 ) * m > n > (2 *(k-1) - 1) * m, 然后我们就必须把k位赋为1, 为什么呢? 你可以想一下 (2 * k - 1 ) * m 了, 然后如果 再不分的话,就会超过m份。
然后我们就看它最多可以分为多少份, 不断地减去,直到分完为止。
首先是java大数代码,存个板子:
import java.math.BigInteger;
import java.util.Scanner;
public class Main
{
public static BigInteger two = BigInteger.valueOf(2);
public static BigInteger one = BigInteger.ONE;
public static BigInteger zero = BigInteger.ZERO;
public static BigInteger n, m;
public static BigInteger a[] = new BigInteger[4005];
public static void init()
{
a[0] = one;
for(int i = 1; i <= 4002; i++)
a[i] = a[i - 1].multiply(two);
}
public static void main(String[] args)
{
Scanner cin = new Scanner(System.in);
int t = cin.nextInt();
init();
while(t > 0)
{
t--;
int up = 0;
n = cin.nextBigInteger();
m = cin.nextBigInteger();
BigInteger sum = zero, temp = n, ans = zero;
for(int i = 0; sum.compareTo(n) < 0; i++)
{
sum = sum.add(m.multiply(a[i]));
up = i;
}
for(int i = up; i >= 0; i--)
{
BigInteger b = a[i].subtract(one);
//if(T.multiply(m).compareTo(temp) >= 0) continue;
if((b.multiply(m)).compareTo(temp) >= 0) continue;
BigInteger k = temp.divide(a[i]); // 可以分为几个
k = k.min(m);
ans = ans.add(a[i]);
temp = temp.subtract(a[i].multiply(k)); // 减去
}
System.out.println(ans);
}
cin.close();
}
}
python 代码:难受的是python2.x快被我忘干净了,3.x语法orz
t = int(input())
while t > 0:
t -= 1
a, b = map(int, raw_input().split())
num = 1
ans = 0
while (num - 1) * b <= a:
num *= 2
while a > 0:
while (num - 1) * b >= a:
num /= 2
ans += num
if num * b < a:
a -= num * b
else:
a = a % num
print ans