洛谷 U138343 炼金术士
题目背景
某日午后,SeawaySeawa**y一觉醒来,发现自己穿越到了十三世纪的欧洲,并成为了一名炼金术士......在反穿越失败后,SeawaySeawa**y接受了这个事实,并尝试着实现每个炼金术士的毕生夙愿——点石成金......
题目描述
经过多年探索,SeawaySeawa**y终于发现了点石成金的奥秘,这涉及到一个自远古传承而来的阵法。其法则是:把NN块质量为11洛夫洛丝(炼金术士所用单位)的石块分成若干堆放到阵法里,阵法会进行判定:如果这些堆石块能拼凑出从11洛夫洛丝到NN洛夫洛丝的所有质量,那么这些石块就会都变成金子。
自然,石块分堆是需要消耗精力的。SeawaySeawa**y贪心地想消耗最少的精力获得金子。那么,请你为他算出:最少把石块分成几堆,使之符合点石成金的要求。
输入格式
从文件alchemist.inalchemist.i**n中读入数据。
一行一个整数NN。
输出格式
输出到文件alchemist.outalchemist.out中。
一行一个整数ansans,表示最少要分几堆。
命题说明:
洛夫洛丝谐音(LoveRose)。
题解:
根据二进制,易得出:每个正整数都可以被分成若干个二的整数次幂之和的形式。
所以只需要把当前的数从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;
}