ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

洛谷 P1920 成功密码 题解

2019-07-17 21:55:36  阅读:211  来源: 互联网

标签:P1920 洛谷 int double unsigned long 题解 ksm return


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

回到正题

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

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

扯回正题

首先,暴力肯定是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);//输出 
    ret

标签:P1920,洛谷,int,double,unsigned,long,题解,ksm,return
来源: https://www.cnblogs.com/Flash-plus/p/11203882.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有