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 }