洛谷 U138343 炼金术士

洛谷 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\n",tot);
	return 0;
}
posted @ 2020-10-30 16:48  Seaway-Fu  阅读(74)  评论(0编辑  收藏  举报