洛谷2759 奇怪的函数

Problem 3. Lemon_Soda
【题目描述】
小可乐惊喜的发现一瓶汽水中了再来一瓶, 他去商店换汽水的时候, 店主 $Lemon$ 和 $Soda$ 打算耍耍他,出了一个难题,而且做不出来就不给汽水喝
这题说的是:
使得$x^x$达到或超过 $n$ 位数字的最小正整数 $x$ 是多少?
小可乐见了两位妹子紧张的不敢说话,快请你帮帮他解决这个难题吧
【输入格式】
一个正整数 n
【输出格式】
使得$x^x$达到 n 位数字的最小正整数 $x$
【输入样例】
11
【输出样例】
10
【说明】
n<=2000000000
换底公式

$$\log_ab=\frac{\log_cb}{\log_ca}$$

 

明显的,数学裸题。春节回来恢复状态。

solution: 可以先观察一下题目所给的式子。设$f(x)=x^x$,解不等式$f(x)>=10^n$.

考虑到数据范围很大,直接枚举什么的都不行。不妨套用数学方法解决,数学做法常见套路就是两边取常用对数。

两边取常用对数:

$$\lg x^x\le\lg n$$

由幂的对数性质:

$$x\lg x\le\lg n$$

这时可以考虑枚举$x$,明显会TLE,考虑优化方案。

由对数函数的性质,常用对数是单调递增函数,可以使用二分优化。

考虑到我们需要求以上不等式的最小整数解,即对解集的边界条件上取整的答案。

不妨二分一个答案$mid$,判断是否满足$\left\lceil mid\lg mid\right\rceil\le n$即可,时间复杂度是$O(\log_22000000000)$,可以通过所有数据。

#include<cstdio>
#include<cmath>
using namespace std;
int l=1,r=0x7fffffff;
long long n;
int main()
{
	scanf("%lld",&n);
	while(l<r)//二分
	{
		int mid=(l+r)>>1;
		double len=1.*mid*log10(mid)+1e-9+1.;//转成double,套套式子,处理浮点误差blahblahblah
		if(len>n)r=mid;
		else l=mid+1;
	}
	printf("%lld",l);
	return 0;
}

代码还是很短的。思维难度简单。

(我能说数学刚刚及格的人都秒了这道题吗?OI的数学题还是比较简单的qwq)

posted @ 2018-02-20 10:23  baka  阅读(196)  评论(0编辑  收藏  举报