找回密码
 欢迎注册
楼主: 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.        
  5.         public static void main(String[] args)
  6.         {
  7.                 long start = System.currentTimeMillis();
  8.                 for (int n = 1;; n++)
  9.                 {
  10.                         long t1 = System.currentTimeMillis();
  11.                         double s9 = 0.0, s0 = 0.0;
  12.                         int d = (int) Math.pow(10, n - 1);
  13.                         for (int i = d; i < 10 * d; i++)
  14.                         {
  15.                                 if (Integer.toString(i).contains("9"))
  16.                                         //还可以用Integer.toString(i).indexOf("9")!=-1,效率稍低
  17.                                         s9 += 1.0 / i;
  18.                                 else
  19.                                 {
  20.                                         s0 += 1.0 / i;
  21.                                 }
  22.                         }
  23.                         System.out.printf("\n当n=%d时:", n);
  24.                         System.out.print("s9=" + s9 + "\ts0=" + s0 + "\t");
  25.                         System.out.println("Elapsed time:"+ (System.currentTimeMillis() - t1) + "ms");
  26.                         if (s9 > s0)
  27.                         {
  28.                                 System.out.println("当n=" + n + "时:s9>s0");
  29.                                 break;
  30.                         }
  31.                 }
  32.                 System.out.println("\nTotal time:"+ (System.currentTimeMillis() - start) + "ms");
  33.         }

  34. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 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.        
  27.         int begin=int( pow(10.0,n-1));
  28.         int end=int( pow(10.0,n))-1;
  29.         s0=s9=0.00;
  30.        
  31.         if (n<=3)
  32.         {
  33.                 for (int j=begin;j<=end;j++)
  34.                 {
  35.                         if ( bitArr[j] )
  36.                                 s9 += 1.00 /j;
  37.                         else
  38.                                 s0 += 1.00 /j;
  39.                 }
  40.         }
  41.         else
  42.         {
  43.                 int base;
  44.                 begin/=1000;
  45.                 end/=1000;

  46.                 for (int i=begin; i<=end;i++)
  47.                 {
  48.                         base =i*1000;
  49.                         if ( include9(i) )
  50.                         {
  51.                                 for (int j=0;j<1000;j++)
  52.                                         s9 += 1.00 /(double)(base+j);
  53.                         }
  54.                         else
  55.                         {
  56.                                 for (int j=0;j<1000;j++)
  57.                                 {
  58.                                         if ( bitArr[j] )
  59.                                                 s9 += 1.00 /(double)(base+j);
  60.                                         else
  61.                                                 s0 += 1.00 /(double)(base+j);
  62.                                 }
  63.                         }
  64.                 }
  65.         }
  66.         time(&sec);
  67.     printf( "n = %d\t%.24s\n", n, ctime(&sec) );
  68.         printf( "s0 = %.15f\ns9 = %.15f\ns0/s9 = %.15f\n\n\n", s0, s9, s0/s9);
  69.        
  70.         return 0;
  71. }

  72. int _tmain(int argc, _TCHAR* argv[])
  73. {
  74.         initBitArray();
  75.         for (int n=1;n<=9;n++)
  76.         {
  77.                 sumAll(n);
  78.         }
  79.         return 0;
  80. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-11-17 15:03:56 | 显示全部楼层
在我的电脑上,gxq 56楼的程序和我这个程序性能相当,只需7秒就得到结果。gxq,能否在你的电脑上测试一下我的这个程序?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-5-18 06:06 , Processed in 0.046414 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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