东北小蟹蟹

[luogu p1035] 级数求和
题面题目传送门题目描述已知: 显然对于任意一个整数$K$,当$n$足够大的时候,$S_n$大于$K$。现给出一个整...
扫描右侧二维码阅读全文
06
2019/11

[luogu p1035] 级数求和

题面

题目传送门

题目描述
已知:$$ S_n=1+\frac{1}{2}+ \frac{1}{3}+\cdots+\frac{1}{n} $$ 显然对于任意一个整数$K$,当$n$足够大的时候,$S_n$大于$K$。
现给出一个整数$K$($1 \le k \le 15$),要求计算出一个最小的$n$;使得$S_n>K$。

输入格式
一个正整数$K$
输出格式
一个正整数$N$
输入输出样例

输入 #1
1
输出 #1
2

正解做法

正解做法的话就是纯模拟啦,这个我就不阐述了。

#include <iostream>
#include <cstdio>
using namespace std;
int k,i;
int main()
{
    double s=0.000000;
    scanf("%d",&k);
    do
    {
        i++;
        s=s+(1.0/i);
    }while(s<=k);
    printf("%d\n",i);
    return 0;
}

一点也不温馨提示:注意精度问题。

非正规做法

首先来看一下数据范围:

数据范围如此之低,我们就能很自然地想到打表了。
所以本篇题解更准确的来说是一个打表教程。
好开始

Step One

首先魔改一下程序,变成这样:

#include <iostream>
#include <cstdio>
using namespace std;
int k,i;
int main()
{
    freopen("C:/Users/we/Desktop/p1035_data.out","w",stdout);
    double s=0.000000;
    for(int k=1;k<=15;k++)
    {
        s=0.000000;
        i=0;
        do
        {
            i++;
            s=s+(1.0/i);
        }while(s<=k);
        printf("\tif(k==%d) return %d;\n",k,i);
    }
    return 0;
}

这其实就是打表的generator啦~
为什么要这么打?还把if啥写上了?
当然是因为方便啦~
同时你又看到了制表符?
当然是因为美观啦~
运行程序,效果如下:
Me9XSx.png

Step Two

把这段复制下来,再魔改一通,就是这样:

#include <iostream>
#include <cstdio>
using namespace std;
int k;
int work()
{
    if(k==1) return 2;
    if(k==2) return 4;
    if(k==3) return 11;
    if(k==4) return 31;
    if(k==5) return 83;
    if(k==6) return 227;
    if(k==7) return 616;
    if(k==8) return 1674;
    if(k==9) return 4550;
    if(k==10) return 12367;
    if(k==11) return 33617;
    if(k==12) return 91380;
    if(k==13) return 248397;
    if(k==14) return 675214;
    if(k==15) return 1835421;

}
int main()
{
    scanf("%d",&k);
    printf("%d\n",work());
    return 0;
}

大功告成,AC满分,而且比正解要运行的快。
打表可是个好东西,有时好好利用它,说不定就有啥惊喜了呢,是吧?

Last modification:November 9th, 2019 at 11:46 am
东北小蟹蟹已经穷的叮当都响不了啦!!qwq

Leave a Comment