2017秦皇岛CCPC G - Numbers(大数,贪心)

G - Numbers :

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3987

题目描述:

  将 n n n分成至多 m m m个非负整数, a 1 a1 a1 a 2 a2 a2 . . . ... ... a k ak ak ( k ≤ m ) (k \leq m) (km),使得 a 1 a1 a1 o r or or a 2 a2 a2 o r or or . . . ... ... o r or or a k ak ak最小。
( 0 ≤ n &lt; 1 0 1000 , 1 ≤ m &lt; 1 0 100 ) (0\leq n&lt;10^{1000}, 1\leq m&lt;10^{100}) (0n<101000,1m<10100)

输入样例:

5
3 1
3 2
3 3
10000 5
1244 10

输出样例:

3
3
1
2000
125

思路:

  对于题目中的 o r or or运算我们首先从二进制出发,不难发现,如果我们分出的数中含有 2 k 2^{k} 2k,那么答案也有 2 k 2^{k} 2k,这就意味着我们可以尽可能多的分出 2 k 2^{k} 2k。那么就是说如果现在存在 m ∗ ( 2 k − 1 ) &lt; n m*(2^{k}-1) &lt; n m(2k1)<n,答案就一定有 2 k 2^{k} 2k这个位,然后贪心的取最多的 2 k 2^{k} 2k更新答案和 n n n就好了。
  对于大数直接用java就好了,因为zoj有py2.7所以我偷懒就用了py,java写法也是一样的。

import sys

pw = []
base = 1
for i in range(0, 4000):
    pw.append(base)
    base <<= 1

T = int(input())
for i in range(T):
    n, m = map(int, raw_input().split()) #python2.7字符串读入用raw_input()
    up, ans = 0, 0
    while pw[up] < n:
        up += 1
    while n and up >= 0:
        if (pw[up] - 1) * m < n:
            ans += pw[up]
            n = max(n - m*pw[up], n % pw[up])
        up -= 1
    print(ans)
sys.exit(0)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值