ZOJ 3987

大力贪心 + 还是要好好学 Python

ZOJ 3987 Numbers

题目描述

给你一个数 $n$ ,分成 $m$ 个数,要求:

  • $\sum ^m _ {i = 1} a_i = n$
  • $\texttt{OR} ^m_{i = 1}$ 最小

题解

对于 $m$ 个数,按位考虑。

对于每一位 $b$ 倒着枚举,如果这一位要填 1,就尽量多填。

  • 怎么多填?每次 $n = \min(n - m * 2^b, n \mod 2^b )$ ,最多填 $m$ 个,否则只能填 $\frac {n} {2 ^ m}$ 个。

AC Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
if __name__ == '__main__':
T = int(input())
for x in range (T):
n, m = map(int, raw_input().split()) #Python 2 的写法
ans = (int)(0)
cnt = 0
ret = (int)(1)
for i in range(10000):
if ret * m - m >= n:
break
ret = ret * 2
while n > 0:
# print("n = ",n,", ret = ",ret,", ans = ",ans)
while (ret - 1) * m >= n:
ret = ret // 2
ans = ans | ret
if ret * m < n:
n -= ret * m
else:
n = n % ret
print(ans)
exit(0)
文章目录
  1. 1. ZOJ 3987 Numbers
    1. 1.1. 题目描述
    2. 1.2. 题解
    3. 1.3. AC Code
{{ live2d() }}