SPOJ—Paying in Byteland

Description

There are infinitely many coin denominations in the Byteland. They have values of 2^i for i=0,1,2,... . We will say that set of coins c1,c2,...,ck is perfect when it is possible to pay every amount of money between 0 and c1+...+ck using some of them (so {4,2,2,1} is perfect while {8,1} is not). The question is - is it always possible to change given sum n into a perfect set of coins? Of course it is possible ;). Your task will be more complicated: for a sum n you should find minimal number of coins in its perfect representation.

Input

First line of input contains one integer c<=50 - number of test cases. Then c lines follow, each of them consisting of exactly one integer n<=10^1000.

Output

For each test case output minimal number of coins.

Sample Input

Input:
5
507
29
8574
233
149

Output:
14
7
21
11
10
 
  
//题意:每个硬币的价值为2^i,现在给出一个n,要求能表示n的最佳perfect representation。 
//最佳perfect representation: 首先必须是perfect representation,即选出的k个硬币能标尺出 1到( k个硬币之和 )内所有的价值。 其次,k要最小。
//首先考虑给出一堆硬币,要求最少硬币表示出价值为n,那么这个数量就是n的二进制下1的个数。因为二进制下n=a*1+b*2+c*4+...(a,b,c...等于1或 0)。 现在要求选出的这些硬币还能标尺出1-n所有的数,n的二进制下形式就不一定满足题意。 如果n恰好等于表达式中所有系数都为1的最终值(n=1*1+1*2+1*4+...1*2^i),那么1-n内所有的数当然可以直接利用这些硬币标尺出(某些系数变为0即可),并且每种硬币只要一个。  而当n不恰好等于1*1+1*2+1*4+1*8....的时候,如29=1*1+1*2+1*4+1*8 + 14. 那么可以利用t=2^1+2^2+2^3+...2^i,2的幂不断增加,最终可以逼近n,而此时选出的这些硬币(2^1,2^2,2^3...2^i)可以表示出1-t内所有的数,最后剩余(n-t)另外用一些硬币来标尺,也就是需要((n-t)二进制下1的个数)个硬币。
import java.util.Scanner;
import java.io.*;
import java.math.*;
import java.math.BigInteger;

public class Main
{
     public static void main(String[] args)
     {
          Scanner cin=new Scanner(System.in);
          int t;
          BigInteger n,tmp;
          t=cin.nextInt();
          while(true)
          {
               if((t--)<=0)
                    break;

               n=cin.nextBigInteger();
               tmp=BigInteger.ONE;
               int ans=0;
               while(true) //tmp=2^1+2^2+2^3+...+2^i。 逼近n
               {
                    if(tmp.compareTo(n)>0)
                         break;
                    ans++;
                    n=n.subtract(tmp);
                    tmp=tmp.multiply(BigInteger.valueOf(2));
               }
               while(true)
               {
                    if(n.compareTo(BigInteger.ZERO)<=0)
                         break;
                    if(n.mod(BigInteger.valueOf(2)).compareTo(BigInteger.ONE)==0)
                         ans++;
                    n=n.divide(BigInteger.valueOf(2));
               }
               System.out.println(ans);
          }
     }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
洛谷的SPOJ需要注册一个SPOJ账号并进行绑定才能进行交题。您可以按照以下步骤进行注册: 1. 打开洛谷网站(https://www.luogu.com.cn/)并登录您的洛谷账号。 2. 在网站顶部导航栏中找到“题库”选项,将鼠标悬停在上面,然后选择“SPOJ”。 3. 在SPOJ页面上,您会看到一个提示,要求您注册SPOJ账号并进行绑定。点击提示中的链接,将会跳转到SPOJ注册页面。 4. 在SPOJ注册页面上,按照要求填写您的用户名、密码和邮箱等信息,并完成注册。 5. 注册完成后,返回洛谷网站,再次进入SPOJ页面。您会看到一个输入框,要求您输入刚刚注册的SPOJ用户名。输入用户名后,点击“绑定”按钮即可完成绑定。 现在您已经成功注册并绑定了SPOJ账号,可以开始在洛谷的SPOJ题库上刷题了。祝您顺利完成编程练习!\[1\]\[2\] #### 引用[.reference_title] - *1* *3* [(洛谷入门系列,适合洛谷新用户)洛谷功能全解](https://blog.csdn.net/rrc12345/article/details/122500057)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [luogu p7492 序列](https://blog.csdn.net/zhu_yin233/article/details/122051384)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值