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

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

[复制链接]
发表于 2010-5-21 11:30:55 | 显示全部楼层
68# wayne 本来就应该这样的,有好的方法当然要用好的
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-5-21 15:03:11 | 显示全部楼层
68# wayne 我没有作弊啊,实质其实一样的,只不过你用了Prepend附加到列表后再组成各数位不含9的数(“Prepend[#, ii] & /@ tmp”,这里不就用到了匿名函数嘛),我的只不过用了另一种途径而已, 殊途同归。 奇怪的是用NSum效率反而会下降。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-5-24 09:29:46 | 显示全部楼层
71# qianyb
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-6-28 21:49:43 | 显示全部楼层
含9的项之和收敛,因此很可能你要找的那个n不存在,盲目地找是没用的。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-6-29 16:48:08 | 显示全部楼层
弄错了,是不含9的项之和收敛,因此所求的n必定存在。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-6-29 17:03:57 | 显示全部楼层
左边分母以i(i=1..8)开头的各有$10^(n-1)-9^(n-1)$项,每项都不小于$10^{1-n}/(i+1)$,以9开头的有$10^(n-1)$项,每项都不小于$10^{-n}$,因此左边大于$(1-0.9^{n-1})(1/2+1/3+...+1/9)+0.1$。类似地,右边分母以i(i=1..8)开头的各有$9^(n-1)$项,每项都不大于$10^{1-n}/i$,因此右边小于$0.9^{n-1}(1+1/2+1/3+...+1/8)$,要求左边大于右边的一个充分条件是$(1-0.9^{n-1})(1/2+1/3+...+1/9)+0.1>0.9^{n-1}(1+1/2+1/3+...+1/8)$,也就是$n\ge 10$就够了。 同样地可以知道左边小于$(1-0.9^{n-1})(1+1/2+1/3+...+1/8)+1/9$,右边大于$0.9^{n-1}(1/2+1/3+...+1/9)$,因此当$n\leq 5$时左边小于右边。综上,所求的n只可能是6,7,8,9,10。 以上只以分母的第一位为比较标准,如果精细一点,以前两位为比较标准,则可以得到所求的n只能是8。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-11-16 20:03:57 | 显示全部楼层
用Mathematica又弄了一种方法,还是构造的,比前面的Mathematica版的代码要快些(计算6位以内耗时<2s):
  1. f[n_] := Module[{t,
  2. arr = Array[1.0/FromDigits[{##}] &, Join[{8}, Array[9 &, n - 1]],
  3. Join[{1}, Array[0 &, n - 1]]]},
  4. {t = Total[arr, Infinity](*Tr@Flatten@seq*),
  5. HarmonicNumber[10^n - 1.0] - HarmonicNumber[10^(n - 1) - 1.0] - t}
  6. ]
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-11-16 21:44:08 | 显示全部楼层
最近学习了Java的字符串类,联系上了这个问题,于是又有了写出来到冲动,同时也用C#写了(大家知道,好多Java code可以稍加修改成为C#的,反之亦然)。发现Java的运行效率竟比C#快不少(网上普遍认为C#一般要比Java稍快,我私下也做过多次比较,他们都有快的时候,谁效率更高似乎没有定论),也许是我不懂C#编译优化选项的缘故。 C++的字符串函数没用过,也许比Java快吧。 另外,在我机子上的测试,相同的Java代码在Linux(我用的Ubuntu,Ubuntu10.10发布后装的)上面比Win上运行效率更高。下面的代码在Windows上面运行14s,而在Linux平台9s。
  1. package string;
  2. public class Is9
  3. {
  4. public static void main(String[] args)
  5. {
  6. long start = System.currentTimeMillis();
  7. for (int n = 1;; n++)
  8. {
  9. long t1 = System.currentTimeMillis();
  10. double s9 = 0.0, s0 = 0.0;
  11. int d = (int) Math.pow(10, n - 1);
  12. for (int i = d; i < 10 * d; i++)
  13. {
  14. if (Integer.toString(i).contains("9"))
  15. //还可以用Integer.toString(i).indexOf("9")!=-1,效率稍低
  16. s9 += 1.0 / i;
  17. else
  18. {
  19. s0 += 1.0 / i;
  20. }
  21. }
  22. System.out.printf("\n当n=%d时:", n);
  23. System.out.print("s9=" + s9 + "\ts0=" + s0 + "\t");
  24. System.out.println("Elapsed time:"+ (System.currentTimeMillis() - t1) + "ms");
  25. if (s9 > s0)
  26. {
  27. System.out.println("当n=" + n + "时:s9>s0");
  28. break;
  29. }
  30. }
  31. System.out.println("\nTotal time:"+ (System.currentTimeMillis() - start) + "ms");
  32. }
  33. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-11-17 14:58:59 | 显示全部楼层
刚刚完成一个一个程序,测试表明,和gxq的速度大抵相当。 这个程序的特点是: 预先算出0-999是否含有数字9,将结果保存在1个1000个字节的数组。 算法很容易理解。 下面是源代码:
  1. #include "stdafx.h"
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <time.h>
  6. char bitArr[1000];
  7. int include9(int i)
  8. {
  9. char buff[12];
  10. _itoa(i,buff,10);
  11. return ( strchr(buff,'9')!=NULL);
  12. }
  13. int initBitArray()
  14. {
  15. int i;
  16. memset(bitArr,0,sizeof(bitArr));
  17. for (i=0;i<1000;i++)
  18. if ( include9(i) )
  19. bitArr[i]=1;
  20. return 0;
  21. }
  22. int sumAll(int n)
  23. {
  24. time_t sec;
  25. double s9,s0;
  26. int begin=int( pow(10.0,n-1));
  27. int end=int( pow(10.0,n))-1;
  28. s0=s9=0.00;
  29. if (n<=3)
  30. {
  31. for (int j=begin;j<=end;j++)
  32. {
  33. if ( bitArr[j] )
  34. s9 += 1.00 /j;
  35. else
  36. s0 += 1.00 /j;
  37. }
  38. }
  39. else
  40. {
  41. int base;
  42. begin/=1000;
  43. end/=1000;
  44. for (int i=begin; i<=end;i++)
  45. {
  46. base =i*1000;
  47. if ( include9(i) )
  48. {
  49. for (int j=0;j<1000;j++)
  50. s9 += 1.00 /(double)(base+j);
  51. }
  52. else
  53. {
  54. for (int j=0;j<1000;j++)
  55. {
  56. if ( bitArr[j] )
  57. s9 += 1.00 /(double)(base+j);
  58. else
  59. s0 += 1.00 /(double)(base+j);
  60. }
  61. }
  62. }
  63. }
  64. time(&sec);
  65. printf( "n = %d\t%.24s\n", n, ctime(&sec) );
  66. printf( "s0 = %.15f\ns9 = %.15f\ns0/s9 = %.15f\n\n\n", s0, s9, s0/s9);
  67. return 0;
  68. }
  69. int _tmain(int argc, _TCHAR* argv[])
  70. {
  71. initBitArray();
  72. for (int n=1;n<=9;n++)
  73. {
  74. sumAll(n);
  75. }
  76. return 0;
  77. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-11-17 15:03:56 | 显示全部楼层
在我的电脑上,gxq 56楼的程序和我这个程序性能相当,只需7秒就得到结果。gxq,能否在你的电脑上测试一下我的这个程序?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-11-24 01:36 , Processed in 0.026056 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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