您的位置:首页 > 其它

一个小学数学题引发的血案

2010-08-15 22:29 232 查看
前几天给弟弟补习的时候发现的这道有意思的题目:

1~5122这个范围内的整数一共有多少个零,例如100就是2个零。

初看到这题的时候让我想到了递归算法(小学真牛逼),可感觉还是很麻烦。大家有没有什么好想法呀,如果能用程序实现更好了





发到论坛上大家讨论了一下。(很意外,这题居然大家讨论得这么火热,刚开始玩csdn,感觉不错^_^)



看到这个题目的时候一开始也是暴力法解决,不过后来发现了其中规律,个人是这么算的。。。



先计算1~10,不用说1个

然后1~100,也就是1*10-0+1=11。

再然后是1~1000,也就是(11+9)*10-9+1=192(9个01……09)

那么5122就是(192+99+9)*5+(11+9)*1+2=1522(99个001……099,9个001……000)



如果数字大,以此类推。。。

1~10000,就是(192+99+9)*10-(99+9)+1=2893

有点动态规划的意思,不过还是过于繁琐。。。于是放到论坛里看看大家的算法。



稍微总结一下,看的几种类型的解法:



首先是这个方法:



穷举,虽然暴力,不过问题是完全解决啦。不多解释了



int i,j,k=0;
for(i=1;i<=5122;i++)
{
j=i;
while(j)
{
if(j%10==0)k++;
j/=10;
}
}




更暴力:



String total="";
for(int i=1;i<=5122;i++){
  total = total +i;
}
//然后在total这个字符串里找0出现了几次




比较好的方法,效率挺高的^_^



//分别计算个十百千等位中0出现的次数
        static int EveryPlaceCountArithmetic()
        {
            int iCount=0;
            int iProxy = 1;
            int n = 5122;
            while (n/iProxy != 0)
            {
                int iDivide = iProxy * 10;
                if (iProxy == 1)//首先计算个位
                    iCount += n / iDivide;
                else
                {
                    int iNextNum = (n % iDivide) / iProxy;//计算个位以上时 判断当前计算位上是否为0
                    if (iNextNum == 0)
                    {
                        iCount += (n / iDivide - 1) * iProxy + 1+n%iDivide;//为0时的计算方法
                    }
                    else
                    {
                        iCount += (n / iDivide)*iProxy;
                    }
                }
                iProxy *= 10;
            }
            return iCount;
        }




如果是用人脑嘛



个位有零情况:5122/10=512

十位有零情况:(5122/100)*10=510//0,1,2……9

百位有零情况:(5122/1000)*100=500

all:1522个0



这个算法最简单,也很快捷。不过对1000,100这样的数时就有问题,是因为计算了01,0101,001这样的东西,去掉就好啦。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: