[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;
}

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

非正规做法

首先来看一下数据范围:
@> 1<=k<=15

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

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满分,而且比正解要运行的快。
打表可是个好东西,有时好好利用它,说不定就有啥惊喜了呢,是吧?

posted @ 2020-02-15 17:22  dbxxx  阅读(237)  评论(0编辑  收藏  举报