CF1037A Packets
题目描述
You have nn coins, each of the same value of 11 .
Distribute them into packets such that any amount xx ( 1 leq x leq n1≤x≤n ) can be formed using some (possibly one or all) number of these packets.
Each packet may only be used entirely or not used at all. No packet may be used more than once in the formation of the single xx , however it may be reused for the formation of other xx 's.
Find the minimum number of packets in such a distribution.
输入格式
The only line contains a single integer nn ( 1 leq n leq 10^91≤n≤109 ) — the number of coins you have.
输出格式
Output a single integer — the minimum possible number of packets, satisfying the condition above.
题意翻译
你有nn个硬币,每个硬币价值都为11。
你要把它们分成若干个小包裹,使得在11与nn之间的所有面额都能用这其中某几个小包裹凑出。
每个小包裹只能作为一个整体使用。
请求出最少要分几个包裹。
输入格式:
一个数nn(1le nle 10^91≤n≤109)。
输出格式:
输出最少要分几个包裹。
样例解释1:
分成33个包裹:[1,2,3][1,2,3],可以凑出11到66中所有的面额。
输入输出样例
输入 #1复制
输出 #1复制
输入 #2复制
输出 #2复制
说明/提示
In the first example, three packets with 11 , 22 and 33 coins can be made to get any amount xx ( 1leq xleq 61≤x≤6 ).
- To get 11 use the packet with 11 coin.
- To get 22 use the packet with 22 coins.
- To get 33 use the packet with 33 coins.
- To get 44 use packets with 11 and 33 coins.
- To get 55 use packets with 22 and 33 coins
- To get 66 use all packets.
In the second example, two packets with 11 and 11 coins can be made to get any amount xx ( 1leq xleq 21≤x≤2 ).
题解:
根据二进制,易得出:每个正整数都可以被分成若干个二的整数次幂之和的形式。
所以只需要把当前的数从2的0次幂开始拆解,拆到最后一共拆出来的部分就是答案。
所以此题可在(O(log N))的复杂度求解。
代码:
#include<cstdio>
using namespace std;
int n,tot,now;
int qpow(int a,int b)
{
int ret=1;
while(b)
{
if(b&1)
ret*=a;
a*=a;
b>>=1;
}
return ret;
}
int main()
{
scanf("%d",&n);
tot=1;
while(tot)
{
now=qpow(2,tot)-1;
if(now>=n)
break;
tot++;
}
printf("%d
",tot);
return 0;
}