找回密码
 欢迎注册
楼主: chyanog

[提问] 当n=?时,含9的项之和开始大于不含9的项之和

[复制链接]
发表于 2010-11-17 16:49:27 | 显示全部楼层
在我的电脑上,gxq 56楼的程序和我这个程序性能相当,只需7秒就得到结果。gxq,能否在你的电脑上测试一下我的这个程序?
liangbch 发表于 2010-11-17 15:03


你的要快多了!

我的56#结果:
n = 1        Wed Nov 17 16:46:05 2010
s0 = 2.717857142857143
s9 = 0.111111111111111
s0/s9 = 24.460714285714285
s0+s9 = 2.828968253968254

n = 2        Wed Nov 17 16:46:05 2010
s0 = 2.053991622224917
s9 = 0.294417641446448
s0/s9 = 6.976455663912790
s0+s9 = 2.348409263671365

n = 3        Wed Nov 17 16:46:05 2010
s0 = 1.817871425200977
s9 = 0.489221917709748
s0/s9 = 3.715842155460231
s0+s9 = 2.307093342910725

n = 4        Wed Nov 17 16:46:05 2010
s0 = 1.633364212583175
s9 = 0.669670962910865
s0/s9 = 2.439054853869453
s0+s9 = 2.303035175494040

n = 5        Wed Nov 17 16:46:05 2010
s0 = 1.469783389239973
s9 = 0.832846704579078
s0/s9 = 1.764770612837813
s0+s9 = 2.302630093819051

n = 6        Wed Nov 17 16:46:05 2010
s0 = 1.322783057766752
s9 = 0.979806535235522
s0/s9 = 1.350045146870536
s0+s9 = 2.302589593002275

n = 7        Wed Nov 17 16:46:06 2010
s0 = 1.190502772693381
s9 = 1.112082770300745
s0/s9 = 1.070516336091988
s0+s9 = 2.302585542994125

n = 8        Wed Nov 17 16:46:07 2010
s0 = 1.071452317287522
s9 = 1.231132820706344
s0/s9 = 0.870297907152530
s0+s9 = 2.302585137993867

n = 9        Wed Nov 17 16:46:27 2010
s0 = 0.964307069526290
s9 = 1.338278027967131
s0/s9 = 0.720558097326824
s0+s9 = 2.302585097493420


你的79#结果:
n = 1        Wed Nov 17 16:46:46 2010
s0 = 2.717857142857143
s9 = 0.111111111111111
s0/s9 = 24.460714285714285


n = 2        Wed Nov 17 16:46:46 2010
s0 = 2.053991622224917
s9 = 0.294417641446448
s0/s9 = 6.976455663912790


n = 3        Wed Nov 17 16:46:46 2010
s0 = 1.817871425200977
s9 = 0.489221917709748
s0/s9 = 3.715842155460231


n = 4        Wed Nov 17 16:46:46 2010
s0 = 1.633364212583175
s9 = 0.669670962910865
s0/s9 = 2.439054853869453


n = 5        Wed Nov 17 16:46:46 2010
s0 = 1.469783389239973
s9 = 0.832846704579078
s0/s9 = 1.764770612837813


n = 6        Wed Nov 17 16:46:46 2010
s0 = 1.322783057766752
s9 = 0.979806535235522
s0/s9 = 1.350045146870536


n = 7        Wed Nov 17 16:46:46 2010
s0 = 1.190502772693381
s9 = 1.112082770300745
s0/s9 = 1.070516336091988


n = 8        Wed Nov 17 16:46:47 2010
s0 = 1.071452317287522
s9 = 1.231132820706344
s0/s9 = 0.870297907152530


n = 9        Wed Nov 17 16:46:55 2010
s0 = 0.964307069526290
s9 = 1.338278027967131
s0/s9 = 0.720558097326824
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-11-17 16:54:23 | 显示全部楼层
看来是 liangbch 的预处理起了很大作用。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-11-17 18:12:05 | 显示全部楼层
60# 无心人
我的方法不新鲜,无心人在60#就提到这个想法,只不过我成功的实现了而已。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-11-17 21:27:36 | 显示全部楼层
根据我的测试,liangbch 和gxqcn两位大牛的代码效率高低不好比较啊。
我用的VC10(装VS2010还不到一个月),在默认Debug的情况下,前者11s,后者22s
,用Release+“使速度最大化”选项编译,多次比较竟然速度一致,均是11s!
不过,用gcc编译,gxqcn的代码+优化选项却不起作用。。。
在Linux上暂未测试
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-11-18 07:42:28 | 显示全部楼层
我的代码已经相当底层了,所以编译器优化不大起作用。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-11-29 00:31:38 | 显示全部楼层
又实现了一种方法,以前想到过,但没写出来。代码比较丑,效率还算不错,在我的笔记本上运行14s。应该是我目前写的行数最多的程序了,感觉肯定能写精简些,但我还简化不了,哪位大牛有空了帮我看看,给点建议。


  1. #include <stdio.h>
  2. #include <time.h>
  3. #include <math.h>

  4. void disp(double s0,double s9)
  5. {
  6.         printf( "s0 = %.15f\ns9 = %.15f\ns0/s9 = %.15f\n\n\n", s0, s9, s0/s9);
  7. }

  8. double calcS(int n)
  9. {
  10.         double s=0.0;
  11.         int i,k;
  12.         k=(int)pow(10.0,n-1);       
  13.         for(i=k;i<10*k;i++)
  14.                 s+=1.0/i;
  15.         return s;          
  16. }
  17. //------------------------------
  18. void search_1()
  19. {
  20.         double s9,s0;
  21.         s9=s0=0.0;
  22.         int a;
  23.         for (a=1;a<=8;a++)   
  24.                 s0+=1.0/a;
  25.         s9=calcS(1)-s0;
  26.         disp(s0,s9);
  27. }

  28. void search_2()
  29. {
  30.         double s9,s0;
  31.         s9=s0=0.0;
  32.         int a,b;
  33.         for (a=1;a<=8;a++)
  34.                 for (b=0;b<=8;b++)        
  35.                         s0+=1.0/(10*a+b);
  36.         s9=calcS(2)-s0;
  37.         disp(s0,s9);
  38. }

  39. void search_3()
  40. {
  41.         double s9,s0,s;
  42.         s9=s0=0.0;
  43.         int a,b,c;
  44.         for (a=1;a<=8;a++)
  45.                 for (b=0;b<=8;b++)
  46.                         for (c=0;c<=8;c++)
  47.                                 s0+=1.0/(100*a+10*b+c);
  48.         s9=calcS(3)-s0;
  49.         disp(s0,s9);
  50. }
  51. void search_4()
  52. {
  53.         double s9,s0,s;
  54.         s9=s0=0.0;
  55.         int a,b,c,d;
  56.         for (a=1;a<=8;a++)
  57.                 for (b=0;b<=8;b++)
  58.                         for (c=0;c<=8;c++)
  59.                                 for (d=0;d<=8;d++)
  60.                                         s0+=1.0/(1000*a+100*b+10*c+d);

  61.         s9=calcS(4)-s0;
  62.         disp(s0,s9);
  63. }

  64. void search_5()
  65. {
  66.         double s9,s0,s;
  67.         s9=s0=0.0;
  68.         int a,b,c,d,e;
  69.         for (a=1;a<=8;a++)
  70.                 for (b=0;b<=8;b++)
  71.                         for (c=0;c<=8;c++)
  72.                                 for (d=0;d<=8;d++)
  73.                                         for (e=0;e<=8;e++)
  74.                                                 s0+=1.0/(10000*a+1000*b+100*c+10*d+e);
  75.         s9=calcS(5)-s0;
  76.         disp(s0,s9);
  77. }

  78. void search_6()
  79. {
  80.         double s9,s0,s;
  81.         s9=s0=0.0;
  82.         int a,b,c,d,e,f;
  83.         for (a=1;a<=8;a++)
  84.                 for (b=0;b<=8;b++)
  85.                         for (c=0;c<=8;c++)
  86.                                 for (d=0;d<=8;d++)
  87.                                         for (e=0;e<=8;e++)
  88.                                                 for (f=0;f<=8;f++)
  89.                                                         s0+=1.0/(100000*a+10000*b+1000*c+100*d+10*e+f);

  90.         s9=calcS(6)-s0;
  91.         disp(s0,s9);
  92. }

  93. void search_7()
  94. {
  95.         double s9,s0,s;
  96.         s9=s0=0.0;
  97.         int a,b,c,d,e,f,g;
  98.         for (a=1;a<=8;a++)
  99.                 for (b=0;b<=8;b++)
  100.                         for (c=0;c<=8;c++)
  101.                                 for (d=0;d<=8;d++)
  102.                                         for (e=0;e<=8;e++)
  103.                                                 for (f=0;f<=8;f++)
  104.                                                         for(g=0;g<=8;g++)
  105.                                                                 s0+=1.0/(1000000*a+100000*b+10000*c+1000*d+100*e+10*f+g);

  106.         s9=calcS(7)-s0;
  107.         disp(s0,s9);
  108. }

  109. void search_8()
  110. {
  111.         double s9,s0,s;
  112.         s9=s0=0.0;
  113.         int a,b,c,d,e,f,g,h;
  114.         for (a=1;a<=8;a++)
  115.                 for (b=0;b<=8;b++)
  116.                         for (c=0;c<=8;c++)
  117.                                 for (d=0;d<=8;d++)
  118.                                         for (e=0;e<=8;e++)
  119.                                                 for (f=0;f<=8;f++)
  120.                                                         for(g=0;g<=8;g++)
  121.                                                                 for(h=0;h<=8;h++)
  122.                                                                         s0+=1.0/(10000000*a+1000000*b+100000*c+10000*d+1000*e+100*f+10*g+h);

  123.         s9=calcS(8)-s0;
  124.         disp(s0,s9);
  125. }

  126. void search_9()
  127. {
  128.         double s9,s0,s;
  129.         s9=s0=0.0;
  130.         int a,b,c,d,e,f,g,h,i;
  131.         for (a=1;a<=8;a++)
  132.                 for (b=0;b<=8;b++)
  133.                         for (c=0;c<=8;c++)
  134.                                 for (d=0;d<=8;d++)
  135.                                         for (e=0;e<=8;e++)
  136.                                                 for (f=0;f<=8;f++)
  137.                                                         for(g=0;g<=8;g++)
  138.                                                                 for(h=0;h<=8;h++)
  139.                                                                         for(i=0;i<=8;i++)
  140.                                                                                 s0+=1.0/(100000000*a+10000000*b+1000000*c+100000*d+10000*e+1000*f+100*g+10*h+i);

  141.         s9=calcS(9)-s0;
  142.         disp(s0,s9);
  143. }

  144. int main()
  145. {
  146.         double t0=clock();
  147.         search_1();
  148.         search_2();
  149.         search_3();
  150.         search_4();
  151.         search_5();
  152.         search_6();
  153.         search_7();
  154.         search_8();
  155.         search_9();
  156.         printf("Elapsed time: %f s\n",(clock()-t0)/CLOCKS_PER_SEC);
  157.         return 0;
  158. }

复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-11-29 09:05:33 | 显示全部楼层
86# chyanog


重新整理了一下,但测试起来,效率似乎没有明显的提升。
  1. #include <stdio.h>
  2. #include <time.h>

  3. void disp(double s0,double s9)
  4. {
  5.     printf( "s0 = %.15f\ns9 = %.15f\ns0/s9 = %.15f\n\n\n", s0, s9, s0/s9);
  6. }

  7. double calcS(int n)
  8. {
  9.     static int b, e=1;
  10.     double s=0.0;
  11.     int k;
  12.     b=e, e*=10;
  13.     for(k=b;k<e;k++)
  14.         s+=1.0/k;
  15.     return s;
  16. }
  17. //------------------------------
  18. void search_1()
  19. {
  20.     double s9,s0=0.0;
  21.     int k;
  22.     for (k=1;k<=8;k++)
  23.         s0+=1.0/k;
  24.     s9=calcS(1)-s0;
  25.     disp(s0,s9);
  26. }

  27. void search_2()
  28. {
  29.     double s9,s0=0.0;
  30.     int a,b,k=10;
  31.     for (b=1;b<=8;b++,k+=1)
  32.         for (a=0;a<=8;a++,k++)
  33.             s0+=1.0/k;
  34.     s9=calcS(2)-s0;
  35.     disp(s0,s9);
  36. }

  37. void search_3()
  38. {
  39.     double s9,s0=0.0;
  40.     int a,b,c,k=100;
  41.     for (c=1;c<=8;c++,k+=10)
  42.         for (b=0;b<=8;b++,k+=1)
  43.             for (a=0;a<=8;a++,k++)
  44.                 s0+=1.0/k;
  45.     s9=calcS(3)-s0;
  46.     disp(s0,s9);
  47. }

  48. void search_4()
  49. {
  50.     double s9,s0=0.0;
  51.     int a,b,c,d,k=1000;
  52.     for (d=1;d<=8;d++,k+=100)
  53.         for (c=0;c<=8;c++,k+=10)
  54.             for (b=0;b<=8;b++,k+=1)
  55.                 for (a=0;a<=8;a++,k++)
  56.                     s0+=1.0/k;
  57.     s9=calcS(4)-s0;
  58.     disp(s0,s9);
  59. }

  60. void search_5()
  61. {
  62.     double s9,s0=0.0;
  63.     int a,b,c,d,e,k=10000;
  64.     for (e=1;e<=8;e++,k+=1000)
  65.         for (d=0;d<=8;d++,k+=100)
  66.             for (c=0;c<=8;c++,k+=10)
  67.                 for (b=0;b<=8;b++,k+=1)
  68.                     for (a=0;a<=8;a++,k++)
  69.                         s0+=1.0/k;
  70.     s9=calcS(5)-s0;
  71.     disp(s0,s9);
  72. }

  73. void search_6()
  74. {
  75.     double s9,s0=0.0;
  76.     int a,b,c,d,e,f,k=100000;
  77.     for (f=1;f<=8;f++,k+=10000)
  78.         for (e=0;e<=8;e++,k+=1000)
  79.             for (d=0;d<=8;d++,k+=100)
  80.                 for (c=0;c<=8;c++,k+=10)
  81.                     for (b=0;b<=8;b++,k+=1)
  82.                         for (a=0;a<=8;a++,k++)
  83.                             s0+=1.0/k;
  84.     s9=calcS(6)-s0;
  85.     disp(s0,s9);
  86. }

  87. void search_7()
  88. {
  89.     double s9,s0=0.0;
  90.     int a,b,c,d,e,f,g,k=1000000;
  91.     for (g=1;g<=8;g++,k+=100000)
  92.         for (f=0;f<=8;f++,k+=10000)
  93.             for (e=0;e<=8;e++,k+=1000)
  94.                 for (d=0;d<=8;d++,k+=100)
  95.                     for (c=0;c<=8;c++,k+=10)
  96.                         for (b=0;b<=8;b++,k+=1)
  97.                             for (a=0;a<=8;a++,k++)
  98.                                 s0+=1.0/k;
  99.     s9=calcS(7)-s0;
  100.     disp(s0,s9);
  101. }

  102. void search_8()
  103. {
  104.     double s9,s0=0.0;
  105.     int a,b,c,d,e,f,g,h,k=10000000;
  106.     for (h=1;h<=8;h++,k+=1000000)
  107.         for (g=0;g<=8;g++,k+=100000)
  108.             for (f=0;f<=8;f++,k+=10000)
  109.                 for (e=0;e<=8;e++,k+=1000)
  110.                     for (d=0;d<=8;d++,k+=100)
  111.                         for (c=0;c<=8;c++,k+=10)
  112.                             for (b=0;b<=8;b++,k+=1)
  113.                                 for (a=0;a<=8;a++,k++)
  114.                                     s0+=1.0/k;
  115.     s9=calcS(8)-s0;
  116.     disp(s0,s9);
  117. }

  118. void search_9()
  119. {
  120.     double s9,s0=0.0;
  121.     int a,b,c,d,e,f,g,h,i,k=100000000;
  122.     for (i=1;i<=8;i++,k+=10000000)
  123.         for (h=0;h<=8;h++,k+=1000000)
  124.             for (g=0;g<=8;g++,k+=100000)
  125.                 for (f=0;f<=8;f++,k+=10000)
  126.                     for (e=0;e<=8;e++,k+=1000)
  127.                         for (d=0;d<=8;d++,k+=100)
  128.                             for (c=0;c<=8;c++,k+=10)
  129.                                 for (b=0;b<=8;b++,k+=1)
  130.                                     for (a=0;a<=8;a++,k++)
  131.                                         s0+=1.0/k;
  132.     s9=calcS(9)-s0;
  133.     disp(s0,s9);
  134. }

  135. int main()
  136. {
  137.     double t0=clock();
  138.     search_1();
  139.     search_2();
  140.     search_3();
  141.     search_4();
  142.     search_5();
  143.     search_6();
  144.     search_7();
  145.     search_8();
  146.     search_9();
  147.     printf("Elapsed time: %f s\n",(clock()-t0)/CLOCKS_PER_SEC);
  148.     return 0;
  149. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-11-29 20:02:22 | 显示全部楼层
本帖最后由 G-Spider 于 2010-11-30 00:15 编辑

整理了一下,瓶颈在n=9时,用时最多,效率没有提升,或许将calcS()通过筛选方式只算与9有关的可能会好一点,(calcS(9)再做减法,代价非常大,占整体时间的一半以上)。还有依赖性(比如:static不是好的开始),这个好消除。
  1. #include <stdio.h>
  2. #include <time.h>

  3. void disp(double s0,double s9,int n)
  4. {
  5.     printf( "s0[%d] = %.15f\ns9[%d] = %.15f\ns0/s9 = %.15f\n\n\n", n,s0,n,s9,s0/s9);
  6. }

  7. double calcS(int n)//n=1,2,3,...,9
  8. {
  9.     int e[10]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
  10.     int k;
  11.     double s=0.0;
  12.     for(k=e[n-1];k<e[n];k++)
  13.         s+=1.0/k;
  14.     return s;
  15. }

  16. //------------------------------
  17. double search_1()
  18. {
  19.     double s9,s0=0.0;
  20.     int k;
  21.     for (k=1;k<=8;k++)
  22.         s0+=1.0/k;
  23.     return s0;

  24. }

  25. double search_2()
  26. {
  27.     double s9,s0=0.0;
  28.     int a,b,k=10;
  29.     for (b=1;b<=8;b++,k+=1)
  30.         for (a=0;a<=8;a++,k++)
  31.             s0+=1.0/k;
  32.     return s0;

  33. }

  34. double search_3()
  35. {
  36.     double s9,s0=0.0;
  37.     int a,b,c,k=100;
  38.     for (c=1;c<=8;c++,k+=10)
  39.         for (b=0;b<=8;b++,k+=1)
  40.             for (a=0;a<=8;a++,k++)
  41.                 s0+=1.0/k;
  42.     return s0;

  43. }

  44. double search_4()
  45. {
  46.     double s9,s0=0.0;
  47.     int a,b,c,d,k=1000;
  48.     for (d=1;d<=8;d++,k+=100)
  49.         for (c=0;c<=8;c++,k+=10)
  50.             for (b=0;b<=8;b++,k+=1)
  51.                 for (a=0;a<=8;a++,k++)
  52.                     s0+=1.0/k;
  53.     return s0;

  54. }

  55. double search_5()
  56. {
  57.     double s9,s0=0.0;
  58.     int a,b,c,d,e,k=10000;
  59.     for (e=1;e<=8;e++,k+=1000)
  60.         for (d=0;d<=8;d++,k+=100)
  61.             for (c=0;c<=8;c++,k+=10)
  62.                 for (b=0;b<=8;b++,k+=1)
  63.                     for (a=0;a<=8;a++,k++)
  64.                         s0+=1.0/k;
  65.     return s0;

  66. }

  67. double search_6()
  68. {
  69.     double s9,s0=0.0;
  70.     int a,b,c,d,e,f,k=100000;
  71.     for (f=1;f<=8;f++,k+=10000)
  72.         for (e=0;e<=8;e++,k+=1000)
  73.             for (d=0;d<=8;d++,k+=100)
  74.                 for (c=0;c<=8;c++,k+=10)
  75.                     for (b=0;b<=8;b++,k+=1)
  76.                         for (a=0;a<=8;a++,k++)
  77.                             s0+=1.0/k;
  78.     return s0;

  79. }

  80. double search_7()
  81. {
  82.     double s9,s0=0.0;
  83.     int a,b,c,d,e,f,g,k=1000000;
  84.     for (g=1;g<=8;g++,k+=100000)
  85.         for (f=0;f<=8;f++,k+=10000)
  86.             for (e=0;e<=8;e++,k+=1000)
  87.                 for (d=0;d<=8;d++,k+=100)
  88.                     for (c=0;c<=8;c++,k+=10)
  89.                         for (b=0;b<=8;b++,k+=1)
  90.                             for (a=0;a<=8;a++,k++)
  91.                                 s0+=1.0/k;
  92.      return s0;

  93. }

  94. double search_8()
  95. {
  96.     double s9,s0=0.0;
  97.     int a,b,c,d,e,f,g,h,k=10000000;
  98.     for (h=1;h<=8;h++,k+=1000000)
  99.         for (g=0;g<=8;g++,k+=100000)
  100.             for (f=0;f<=8;f++,k+=10000)
  101.                 for (e=0;e<=8;e++,k+=1000)
  102.                     for (d=0;d<=8;d++,k+=100)
  103.                         for (c=0;c<=8;c++,k+=10)
  104.                             for (b=0;b<=8;b++,k+=1)
  105.                                 for (a=0;a<=8;a++,k++)
  106.                                     s0+=1.0/k;
  107.    return s0;

  108. }

  109. double search_9()
  110. {
  111.     double s9,s0=0.0;
  112.     int a,b,c,d,e,f,g,h,i,k=100000000;
  113.     for (i=1;i<=8;i++,k+=10000000)
  114.         for (h=0;h<=8;h++,k+=1000000)
  115.             for (g=0;g<=8;g++,k+=100000)
  116.                 for (f=0;f<=8;f++,k+=10000)
  117.                     for (e=0;e<=8;e++,k+=1000)
  118.                         for (d=0;d<=8;d++,k+=100)
  119.                             for (c=0;c<=8;c++,k+=10)
  120.                                 for (b=0;b<=8;b++,k+=1)
  121.                                     for (a=0;a<=8;a++,k++)
  122.                                         s0+=1.0/k;
  123.    return s0;

  124. }
  125. int main()
  126. {
  127.     double  s0[10]={0};
  128.     double  s9[10]={0};
  129.     double  t0=clock();

  130.     s0[1]=search_1();
  131.     s0[2]=search_2();
  132.     s0[3]=search_3();
  133.     s0[4]=search_4();
  134.     s0[5]=search_5();
  135.     s0[6]=search_6();
  136.     s0[7]=search_7();
  137.     s0[8]=search_8();
  138.     s0[9]=search_9();

  139.             
  140.     s9[1]=calcS(1)-s0[1];
  141.     disp(s0[1],s9[1],1);
  142.     s9[2]=calcS(2)-s0[2];
  143.     disp(s0[2],s9[2],2);  
  144.     s9[3]=calcS(3)-s0[3];
  145.     disp(s0[3],s9[3],3);
  146.     s9[4]=calcS(4)-s0[4];
  147.     disp(s0[4],s9[4],4);
  148.     s9[5]=calcS(5)-s0[5];
  149.     disp(s0[5],s9[5],5);  
  150.     s9[6]=calcS(6)-s0[6];
  151.     disp(s0[6],s9[6],6);
  152.     s9[7]=calcS(7)-s0[7];
  153.     disp(s0[7],s9[7],7);            
  154.     s9[8]=calcS(8)-s0[8];
  155.     disp(s0[8],s9[8],8);
  156.     s9[9]=calcS(9)-s0[9];
  157.     disp(s0[9],s9[9],9);
  158.             
  159.     printf("Elapsed time: %f s\n",(clock()-t0)/CLOCKS_PER_SEC);
  160.     system("Pause");
  161.     return 0;
  162. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-11-30 10:02:23 | 显示全部楼层

考虑到一个现象,发现做减法有个好处,我们知道欧拉公式,lim(1+1/2+1/3+……+1/n) =In(n)+ C     
从n=8开始,可以满足本题的精度要求,所以有如下估计式
1/10000000+1/10000001+...+1/99999999=ln(99999999/9999999)     这个常数用系统自带的计算器就可以算出来
同理n=9以可以算出。
这样一来,时间缩短了1/3。以前上面的程序在我机子上要运行9.16s    ,现在只需要2.59s
(小数点前6位均准确,所以下面的结果只输出了前6位(这无效率影响,上面的9.16s也是只输出前6位的时间))
  1. #include <stdio.h>
  2. #include <time.h>

  3. void disp(double s0,double s9,int n)
  4. {
  5.     printf( "s0[%d] = %.6f\ns9[%d] = %.6f\ns0/s9 = %.6f\n\n\n", n,s0,n,s9,s0/s9);
  6. }

  7. double calcS(int n)//n=1,2,3,...,7
  8. {
  9.     int e[10]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
  10.     int k;
  11.     double s=0.0;
  12.     for(k=e[n-1];k<e[n];k++)
  13.         s+=1.0/k;
  14.     return s;
  15. }

  16. //------------------------------
  17. double search_1()
  18. {
  19.     double s9,s0=0.0;
  20.     int k;
  21.     for (k=1;k<=8;k++)
  22.         s0+=1.0/k;
  23.     return s0;

  24. }

  25. double search_2()
  26. {
  27.     double s9,s0=0.0;
  28.     int a,b,k=10;
  29.     for (b=1;b<=8;b++,k+=1)
  30.         for (a=0;a<=8;a++,k++)
  31.             s0+=1.0/k;
  32.     return s0;

  33. }

  34. double search_3()
  35. {
  36.     double s9,s0=0.0;
  37.     int a,b,c,k=100;
  38.     for (c=1;c<=8;c++,k+=10)
  39.         for (b=0;b<=8;b++,k+=1)
  40.             for (a=0;a<=8;a++,k++)
  41.                 s0+=1.0/k;
  42.     return s0;

  43. }

  44. double search_4()
  45. {
  46.     double s9,s0=0.0;
  47.     int a,b,c,d,k=1000;
  48.     for (d=1;d<=8;d++,k+=100)
  49.         for (c=0;c<=8;c++,k+=10)
  50.             for (b=0;b<=8;b++,k+=1)
  51.                 for (a=0;a<=8;a++,k++)
  52.                     s0+=1.0/k;
  53.     return s0;

  54. }

  55. double search_5()
  56. {
  57.     double s9,s0=0.0;
  58.     int a,b,c,d,e,k=10000;
  59.     for (e=1;e<=8;e++,k+=1000)
  60.         for (d=0;d<=8;d++,k+=100)
  61.             for (c=0;c<=8;c++,k+=10)
  62.                 for (b=0;b<=8;b++,k+=1)
  63.                     for (a=0;a<=8;a++,k++)
  64.                         s0+=1.0/k;
  65.     return s0;

  66. }

  67. double search_6()
  68. {
  69.     double s9,s0=0.0;
  70.     int a,b,c,d,e,f,k=100000;
  71.     for (f=1;f<=8;f++,k+=10000)
  72.         for (e=0;e<=8;e++,k+=1000)
  73.             for (d=0;d<=8;d++,k+=100)
  74.                 for (c=0;c<=8;c++,k+=10)
  75.                     for (b=0;b<=8;b++,k+=1)
  76.                         for (a=0;a<=8;a++,k++)
  77.                             s0+=1.0/k;
  78.     return s0;

  79. }

  80. double search_7()
  81. {
  82.     double s9,s0=0.0;
  83.     int a,b,c,d,e,f,g,k=1000000;
  84.     for (g=1;g<=8;g++,k+=100000)
  85.         for (f=0;f<=8;f++,k+=10000)
  86.             for (e=0;e<=8;e++,k+=1000)
  87.                 for (d=0;d<=8;d++,k+=100)
  88.                     for (c=0;c<=8;c++,k+=10)
  89.                         for (b=0;b<=8;b++,k+=1)
  90.                             for (a=0;a<=8;a++,k++)
  91.                                 s0+=1.0/k;
  92.      return s0;

  93. }

  94. double search_8()
  95. {
  96.     double s9,s0=0.0;
  97.     int a,b,c,d,e,f,g,h,k=10000000;
  98.     for (h=1;h<=8;h++,k+=1000000)
  99.         for (g=0;g<=8;g++,k+=100000)
  100.             for (f=0;f<=8;f++,k+=10000)
  101.                 for (e=0;e<=8;e++,k+=1000)
  102.                     for (d=0;d<=8;d++,k+=100)
  103.                         for (c=0;c<=8;c++,k+=10)
  104.                             for (b=0;b<=8;b++,k+=1)
  105.                                 for (a=0;a<=8;a++,k++)
  106.                                     s0+=1.0/k;
  107.    return s0;

  108. }

  109. double search_9()
  110. {
  111.     double s9,s0=0.0;
  112.     int a,b,c,d,e,f,g,h,i,k=100000000;
  113.     for (i=1;i<=8;i++,k+=10000000)
  114.         for (h=0;h<=8;h++,k+=1000000)
  115.             for (g=0;g<=8;g++,k+=100000)
  116.                 for (f=0;f<=8;f++,k+=10000)
  117.                     for (e=0;e<=8;e++,k+=1000)
  118.                         for (d=0;d<=8;d++,k+=100)
  119.                             for (c=0;c<=8;c++,k+=10)
  120.                                 for (b=0;b<=8;b++,k+=1)
  121.                                     for (a=0;a<=8;a++,k++)
  122.                                         s0+=1.0/k;
  123.    return s0;

  124. }
  125. int main()
  126. {
  127.     double  s0[10]={0};
  128.     double  s9[10]={0};
  129.     //由欧拉公式lim(1+1/2+...+1/n)=lnn+C  (n->无穷,c为常数)
  130.     //从第n=8开始,n值以达到其极限的精度要求
  131.   //完全可以用估计式ln( n/m )=1/n +1/(n-1)+...+1/(m+1)
  132.     //这样明显减少计算时间
  133.   double  s_8=2.3025851829940506340183244547094;
  134.     double  s_9=2.3025851019940457335179917876844;

  135.     double  t0=clock();

  136.     s0[1]=search_1();
  137.     s0[2]=search_2();
  138.     s0[3]=search_3();
  139.     s0[4]=search_4();
  140.     s0[5]=search_5();
  141.     s0[6]=search_6();
  142.     s0[7]=search_7();
  143.     s0[8]=search_8();
  144.     s0[9]=search_9();

  145.             
  146.     s9[1]=calcS(1)-s0[1];
  147.     disp(s0[1],s9[1],1);
  148.     s9[2]=calcS(2)-s0[2];
  149.     disp(s0[2],s9[2],2);  
  150.     s9[3]=calcS(3)-s0[3];
  151.     disp(s0[3],s9[3],3);
  152.     s9[4]=calcS(4)-s0[4];
  153.     disp(s0[4],s9[4],4);
  154.     s9[5]=calcS(5)-s0[5];
  155.     disp(s0[5],s9[5],5);  
  156.     s9[6]=calcS(6)-s0[6];
  157.     disp(s0[6],s9[6],6);
  158.     s9[7]=calcS(7)-s0[7];
  159.     disp(s0[7],s9[7],7);            
  160.     //==================     
  161.     s9[8]=s_8-s0[8];
  162.     disp(s0[8],s9[8],8);
  163.     s9[9]=s_9-s0[9];   
  164.     disp(s0[9],s9[9],9);
  165.             
  166.     printf("Elapsed time: %f s\n",(clock()-t0)/CLOCKS_PER_SEC);
  167.     system("Pause");
  168.     return 0;
  169. }
复制代码
结果:
s0[1] = 2.717857
s9[1] = 0.111111
s0/s9 = 24.460714


s0[2] = 2.053992
s9[2] = 0.294418
s0/s9 = 6.976456


s0[3] = 1.817871
s9[3] = 0.489222
s0/s9 = 3.715842


s0[4] = 1.633364
s9[4] = 0.669671
s0/s9 = 2.439055


s0[5] = 1.469783
s9[5] = 0.832847
s0/s9 = 1.764771


s0[6] = 1.322783
s9[6] = 0.979807
s0/s9 = 1.350045


s0[7] = 1.190503
s9[7] = 1.112083
s0/s9 = 1.070516


s0[8] = 1.071452
s9[8] = 1.231133
s0/s9 = 0.870298


s0[9] = 0.964307
s9[9] = 1.338278
s0/s9 = 0.720558


Elapsed time: 2.599000 s
请按任意键继续. . .
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-11-30 10:16:36 | 显示全部楼层
根据欧拉定理,所有的n位正整数的倒数和$=ln(10^n)-ln(10^(n-1))=ln10=2.3025850929940456840179914546844$
上述式子当n比较大时成立,也即 无心人 的 $s0+s9$
gxqcn 发表于 2010-5-19 14:59



楼上的与我在22#想的一致,所以的我程序特意输出了“s0+s9
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-5-3 22:56 , Processed in 0.048532 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表