洛谷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)