HDU 5879 Cure

Cure

  Given an integer nn, we only want to know the sum of 1/k21/k2 where kk from 11 to nn.

Input

  There are multiple cases. 
  For each test case, there is a single line, containing a single positive integer nn. 
  The input file is at most 1M. 
Output

  The required sum, rounded to the fifth digits after the decimal point.

Sample Input

1
2
4
8
15

Sample Output

1.00000
1.25000
1.42361
1.52742
1.58044


解题思路:
  本题有多组测试数据,每组数据给出一个数n,数字k为从1到n所有整数,要求求和所有1/k^2。

  由于k越来越大,1/k^2越来越小,而我们只需要输出小数点后5位,在疯狂wa11次尝试之后我发现当k到1e6左右,对于加上所有k>1e6时的1/k^2对答案都没用影响了,小数点后5位就不会变动了。那么我们只需要将所有1~1e6的结果打表计算一次,如果输入的数大于1e6那之间输出1e6时的结果即可。

  还有一个坑就是,本题没有给出输入的数n的范围,这证明什么?n无限大!还是用字符串存吧。

AC代码

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn = 1e6;
 5 double sum[maxn];   //sum记录对于从1~1e6所有n的答案
 6 int main()
 7 {
 8     string s;   //s记录输入的数
 9     double ans = 1.0;
10     sum[1] = 1.0;   //n为1时1/1^2 = 1.0
11     for(int i = 2; i <= maxn; i++){
12             ans += (double)(1.0 / i )* (double)(1.0 / i );
13             sum[i] = ans;   //打表所有1~1e6的答案
14     }
15     while(cin >> s){    //输入字符串s
16         int n = 0;
17         if(s.size() <= 6){  //判断s所代表的数字长度是否超过6
18             for(int i = 0; i < s.size(); i++){
19                 n = n * 10 + s[i] - '0';
20             }
21             //字符串长度不超过6将转换为数字后判断与1e6的关系
22             if(n < maxn){
23                 printf("%.5f\n", sum[n]);
24                 //n小于1e6直接输出答案
25             }else{
26                 //n大于1e6直接输出1e6时的答案
27                 ans = sum[maxn];
28                 printf("%.5f\n", ans);
29             }
30         }else{
31             //长度超过6连拆成数字都不用直接输出1e6时的答案
32             printf("%.5f\n", sum[maxn]);
33         }
34 
35     }
36     return 0;
37 }

 

posted @ 2018-11-28 20:32  suvvm  阅读(208)  评论(0编辑  收藏  举报