洛谷p3152

题目描述

kkk制造了一个序列,这个序列里的数全是由正整数构成的。你别认为她的数列很神奇——其实就是1, 2, …, n而已。当然,n是给定的。kkk的同学lzn认为0是一个好数字(看上去很饱满有木有),所以他机智的趁kkk不在把这个序列全变成了0(其实只是准备窝)~

可是kkk突然回来了!于是lzn的计划破灭了。但是他并不甘心,就和kkk说:我可以每次从这个序列中选取一些数,然后一起减去一个相同的数(当然也是正整数)。然后经过有(wu)限(qiong)次这样的操作后,这个序列就可以全变成0。

kkk当然不信咯,于是lzn就求出了他最少要做几次这样的操作,才能使这个序列全部变成0。

输入格式

一个正整数n

输出格式

最少操作次数

如果无解输出-1

输入输出样例

输入 #1
2
输出 #1
2

说明/提示

1<=n<=1

#include<iostream>
#include<cmath>
using namespace std;
int main()
{
long long t;
cin>>t;
cout<<(int)log2(t)+1;
return 0;
}

新学了一个函数,这个题的标签是数论+递归,但是因为我数论学的跟shift一样我一开始看这个题的时候一脸疑惑,所以我借鉴了一下题解里面的思路。首先代码很简单,解释一下log这个函数属于cmath函数库的,log2(t)的意思是求以二为底t的对数,至于括号里的int型之后再解释。

根据非常简单的数论基本常识,所有的正整数都可以用不大于2的n次方+1个互不相同的2的n次方相加的形式来表示,这里的n可以随便取(随便取的意思是最终都能表示出需要表示的正整数),当我们把正整数表示成2一堆次方相加之后我们会发现,每次只能减去一个数的最优情况是每次消掉一个2的n次方,那么这个数列的最短步骤数就取决于数列中最大的数的操作数,最大的数能被表示成多少个2的n次方相加,操作数就是多少(2^0也算1此操作)。所以我们就可以用log函数求n了(这里的n的意思是多个2的n次方相加中最后一项的n),然后操作数+1(算上n=0的情况)就可以了,然后我们发现log函数前面的括号里为什么有一个int鸭?因为我们要求的是操作数,这里的意思是log函数的数据类型变成int型,如果不打的话,最后输出的答案中会带有小数位,这里会对实际值向下取整。

 

posted @ 2020-05-17 16:41  头顶凉风  阅读(118)  评论(0编辑  收藏  举报