1 条题解

  • 0
    @ 2025-8-24 21:31:55

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Tarsal
    退役了。

    搬运于2025-08-24 21:31:55,当前版本为作者最后更新于2019-07-16 22:16:15,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    这是蒟蒻的第一篇题解,(之前的都没过,估计这篇也过不了

    回到正题

    这题,本蒟蒻第一眼看到以后,就决定咦,这不是模拟吗?

    看到世界范围,嗯,打扰了。

    扯回正题

    首先,暴力肯定是A不了的(至少我A不了

    但是,身为蒟蒻的我,还是打了一个暴力。

    #include<bits/stdc++.h>
    using namespace std;
    
    double x, ans;
    unsigned long long n;
    
    double mypow(double x, int y)
    {
        double sum = 1;
        while(y --)
            sum *= x;
        return sum;
    }
    
    int main()
    {
        scanf("%lf%u", &x, &n);
        for(int i = 1; i <= n; ++ i)
            ans += mypow(x, i) / i;
        printf("%.4lf\n", ans);
        return 0;
    }
    

    不出意外,0分,12000ms,全T;

    然后,认真分析,这是一道数学题。嗯(废话

    用快速幂优化试下

    #include<bits/stdc++.h>
    using namespace std;
    
    double x, ans;
    unsigned long long n;
    
    double ksm(double x, unsigned long long y)
    {
        if(y == 1)
            return x;
        if(y & 1)
            return ksm(x * x, y >> 1) * x;
        return ksm(x * x, y >> 1);
    }
    
    int main()
    {
        scanf("%lf%u", &x, &n);
        for(int i = 1; i <= n; ++ i)
            ans += ksm(x, i) / i;
        printf("%.4lf\n", ans);
        return 0;
    }
    

    嗯,高一点,30分,8520ms,后面的还是T了,

    我们T掉的原因是什么?

    就是我们求和那里跑了太多次,而i越的,x的i次方就越小,又因为它的精度要求只有4位,

    所以,后面有很多次都是白跑的,对结果没影响。

    那就,不跑。

    嗯,在输入完n以后,判断一下,是否比maxn大

    如果大的话,就赋n为maxn;

    好,现在的问题又转化成了,maxn应该取什么值;

    maxn应该取一个什么样的值?

    它要使得,在它后面的数相加小于0.00005;

    额,我最开始随便取了一个值,300

    结果,80分,海星;

    继续扩大maxn,因为,时间相对还算充裕,我就赋大了一点,赋到了7233,就A了;

    好,接下来就是愉快的代码时间了

    #include<bits/stdc++.h>
    using namespace std;
    
    double x, ans;
    unsigned long long n;//开无符号更保险, 
    
    //这是递归版的快速幂 
    double ksm(double x, unsigned long long y)
    {
    	if(y == (unsigned long long) 1)
    		return x;
    	if(y & 1)
    		return ksm(x * x, y >> 1) * x;
    	return ksm(x * x, y >> 1);
    }
    
    //这是循环版的快速幂 
    /*
    double ksm(double x, unsigned long long y)
    {
    	double ans = 1, base = x;
    	while(y != 0)
    	{
    		if(y & 1 != 0)
    			ans *= base;
    		base *= base;
    		y >>= 1;
    	}
    	return ans;
    }
    */
     
    int main()
    {
    	scanf("%lf%ull", &x, &n);//输入 
    	if(n >= 72333)//奇葩的特判,我觉得这是骗分。。。 
    		n = 72333;
    	for(double i = 1.0; i <= (double) n; ++ i)//嗯,i的类型定义为double更好 
    		ans += ksm(x, i) / i;//递推式,不说;
    	printf("%.4lf\n", ans);//输出 
    	return 0;//愉快的结束。 
    }
    
    • 1

    信息

    ID
    888
    时间
    1000ms
    内存
    125MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者