题目链接:http://lightoj.com/volume_showproblem.php?problem=1234

 

 

Sample Input
12
1
2
3
4
5
6
7
8
9
90000000
99999999
100000000
Sample Output
Case 1: 1
Case 2: 1.5
Case 3: 1.8333333333
Case 4: 2.0833333333
Case 5: 2.2833333333
Case 6: 2.450
Case 7: 2.5928571429
Case 8: 2.7178571429
Case 9: 2.8289682540
Case 10: 18.8925358988
Case 11: 18.9978964039
Case 12: 18.9978964139

 

分析:这个是高数的东西 发散 n足够大时它无穷大 直接公式解。

1.虽然输出五花八门,但是不用管它,精度能保证在10 ^-8就没问题,直接用%.10lf 即可;

2. n的范围是10^8,肯定不能正常跑,但是我们有公式,不怕,前面10000个可以正常打表,后面的我们就用公式,再说了,这个公式能成立,本来就是在n比较大的时候,公式如下:  r为常数,r=0.57721566490153286060651209(r就是欧拉常数)。

特别注意,由于题目要求精度为10^-8,常数r也是前人推导出来的,然而也只推导了有限位数,所以正常利用这个公式,并不能达到精度要求,我们只好比较样例和我们自己输出的数据,增添一些可行的项,经尝试,在原公式的基础上,再减去一个1.0/(2*n)恰好可以满足精度,也算是投机取巧了。

 

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<queue>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<iostream>
 8 
 9 using namespace std;
10 typedef long long LL;
11 
12 #define INF 0x3f3f3f3f
13 #define N 12000
14 #define mod 1000000007
15 #define R 0.57721566490153286060651209///R就是欧拉常数
16 
17 double a[N];
18 
19 int main()
20 {
21     int T,k,i,x;
22     double sum=0.0;
23 
24     a[1]=1;
25     for(i=2;i<=10000;i++)
26         a[i]=a[i-1]+1.0/i;
27 
28     scanf("%d", &T);
29 
30     k=1;
31     while(T--)
32     {
33         printf("Case %d: ", k++);
34         scanf("%d", &x);
35         if(x<=10000)
36             printf("%.10f\n", a[x]);
37         else
38         {
39             sum=log(x+1)+R-1.0/(2*x);
40             printf("%.10f\n", sum);
41         }
42     }
43     return 0;
44 }
45 /*sum=log(n+1)+R-1.0/(2*n);*/

 

有大神说:可以思维逆转,让我们用另一种思路再去看这个题目。

如果只靠打表,而且是有技术含量的打表,也能很好的解决这个问题,既然10^8的表我们打不出来,但是200万的表我们还是能打的,这样一来,我们先平均分而且间隔着,每50个记录一个,先把分布在10^8数据中的值放在表里,真正计算时,我们便先找到距离我们的n最近的且小于n的在表中存过数据的一个数,然后再在这个数的基础上递推这往下算,这样一来,便大大降低了时间复杂度,太啰嗦了,还是看代码吧!

 

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<queue>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<iostream>
 8 
 9 using namespace std;
10 typedef long long LL;
11 
12 #define INF 0x3f3f3f3f
13 #define N 2100000
14 #define MAXN 100000000
15 #define mod 1000000007
16 #define R 0.57721566490153286060651209///R就是欧拉常数
17 
18 double a[N];
19 
20 int main()
21 {
22     int T,k,i,x,c;
23     double sum=0.0;
24 
25     a[0]=0;
26     c=1;
27     for(i=1;i<=MAXN;i++)
28     {
29          sum+=1.0/i;
30          if(i%50==0)
31             a[c++]=sum;
32     }
33 
34     scanf("%d", &T);
35 
36     k=1;
37     while(T--)
38     {
39 
40         scanf("%d", &x);
41 
42         int num=x/50;
43         double s;
44         s=a[num];
45         for(i=50*num+1;i<=x;i++)
46         s+=1.0/i;
47        printf("Case %d: %.10f\n", k++, s);
48     }
49     return 0;
50 }
51 /*sum=log(n+1)+R-1.0/(2*n);*/

 

posted on 2016-08-04 16:35  惟愿。。。  阅读(538)  评论(0编辑  收藏  举报