qianyb 发表于 2010-5-21 11:30:55

68# wayne


本来就应该这样的,有好的方法当然要用好的

chyanog 发表于 2010-5-21 15:03:11

68# wayne
我没有作弊啊,实质其实一样的,只不过你用了Prepend附加到列表后再组成各数位不含9的数(“Prepend[#, ii] & /@ tmp”,这里不就用到了匿名函数嘛),我的只不过用了另一种途径而已,
殊途同归。
奇怪的是用NSum效率反而会下降。

wayne 发表于 2010-5-24 09:29:46

71# qianyb


:dizzy:

Buffalo 发表于 2010-6-28 21:49:43

含9的项之和收敛,因此很可能你要找的那个n不存在,盲目地找是没用的。

Buffalo 发表于 2010-6-29 16:48:08

弄错了,是不含9的项之和收敛,因此所求的n必定存在。

Buffalo 发表于 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。

chyanog 发表于 2010-11-16 20:03:57

用Mathematica又弄了一种方法,还是构造的,比前面的Mathematica版的代码要快些(计算6位以内耗时<2s):
f := Module[{t,
   arr = Array &, Join[{8}, Array],
   Join[{1}, Array]]},
{t = Total(*Tr@Flatten@seq*),
   HarmonicNumber - HarmonicNumber - t}
]

chyanog 发表于 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。
package string;

public class Is9
{
       
        public static void main(String[] args)
        {
                long start = System.currentTimeMillis();
                for (int n = 1;; n++)
                {
                        long t1 = System.currentTimeMillis();
                        double s9 = 0.0, s0 = 0.0;
                        int d = (int) Math.pow(10, n - 1);
                        for (int i = d; i < 10 * d; i++)
                        {
                                if (Integer.toString(i).contains("9"))
                                        //还可以用Integer.toString(i).indexOf("9")!=-1,效率稍低
                                        s9 += 1.0 / i;
                                else
                                {
                                        s0 += 1.0 / i;
                                }
                        }
                        System.out.printf("\n当n=%d时:", n);
                        System.out.print("s9=" + s9 + "\ts0=" + s0 + "\t");
                        System.out.println("Elapsed time:"+ (System.currentTimeMillis() - t1) + "ms");
                        if (s9 > s0)
                        {
                                System.out.println("当n=" + n + "时:s9>s0");
                                break;
                        }
                }
                System.out.println("\nTotal time:"+ (System.currentTimeMillis() - start) + "ms");
        }

}

liangbch 发表于 2010-11-17 14:58:59

刚刚完成一个一个程序,测试表明,和gxq的速度大抵相当。
这个程序的特点是:
   预先算出0-999是否含有数字9,将结果保存在1个1000个字节的数组。
   算法很容易理解。
下面是源代码:
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

char bitArr;

int include9(int i)
{
        char buff;
        _itoa(i,buff,10);
        return ( strchr(buff,'9')!=NULL);
}

int initBitArray()
{
        int i;
        memset(bitArr,0,sizeof(bitArr));
        for (i=0;i<1000;i++)
                if ( include9(i) )
                        bitArr=1;
        return 0;
}


int sumAll(int n)
{
        time_t sec;
        double s9,s0;
       
        int begin=int( pow(10.0,n-1));
        int end=int( pow(10.0,n))-1;
        s0=s9=0.00;
       
        if (n<=3)
        {
                for (int j=begin;j<=end;j++)
                {
                        if ( bitArr )
                                s9 += 1.00 /j;
                        else
                                s0 += 1.00 /j;
                }
        }
        else
        {
                int base;
                begin/=1000;
                end/=1000;

                for (int i=begin; i<=end;i++)
                {
                        base =i*1000;
                        if ( include9(i) )
                        {
                                for (int j=0;j<1000;j++)
                                        s9 += 1.00 /(double)(base+j);
                        }
                        else
                        {
                                for (int j=0;j<1000;j++)
                                {
                                        if ( bitArr )
                                                s9 += 1.00 /(double)(base+j);
                                        else
                                                s0 += 1.00 /(double)(base+j);
                                }
                        }
                }
        }
        time(&sec);
    printf( "n = %d\t%.24s\n", n, ctime(&sec) );
        printf( "s0 = %.15f\ns9 = %.15f\ns0/s9 = %.15f\n\n\n", s0, s9, s0/s9);
       
        return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
        initBitArray();
        for (int n=1;n<=9;n++)
        {
                sumAll(n);
        }
        return 0;
}

liangbch 发表于 2010-11-17 15:03:56

在我的电脑上,gxq 56楼的程序和我这个程序性能相当,只需7秒就得到结果。gxq,能否在你的电脑上测试一下我的这个程序?
页: 1 2 3 4 5 6 7 [8] 9 10
查看完整版本: 当n=?时,含9的项之和开始大于不含9的项之和