首页 新闻 会员 周边

统计1到N之间数字1的个数

0
[已解决问题] 解决于 2013-08-04 13:28

为迎接祖国生日,yuyu的幼儿园举办了唱歌比赛,家长小朋友们也都一起来观看了,他们被老师安排在m行n列的小凳子上,家长为了近距离目睹自己孩子唱歌时的风采,都纷纷抢占有利的位置,可是还是有很多家长被前面的高个子挡住了视线(如果前面有人比自己高就算被挡住视线),一时间怨声四起,场内的怨声差点盖过了小朋友的歌声。现在就让你统计一下被挡住视线的人数占总人数的比例。

 

输入 

输入数据有多组,每组的第一行为两个正整数m和n(1<=m, n<=100),接下来有m行,每行n个非负整数,每个整数如果为0表示该位置为空,否则表示该位置上家长的高度。
输入以0 0结束。 

输出 

每组输出一个百分比表示的小数,表示被挡住视线的人数占总人数的比例,保留1位小数。 

样例输入 

3 3
1 2 3
3 2 1
2 1 3
0 0 

样例输出 

33.3% 
坚持、沉默~的主页 坚持、沉默~ | 菜鸟二级 | 园豆:204
提问于:2013-08-01 12:37
< >
分享
最佳答案
0

对于一个数字中的任何第k位出现1的次数,分为两个阶段:

1. 其高位(>k的那些为,k从低位开始计数)有多大的概率使得k位出现1

2. 每次第k为出现1之后,这个1能保持多长时间。

举个例子:

n=3243,k=2,即十位上的那个数字m[k]=4

1. 显然,十位上出现1的次数是 n%100,即:如果我让十位上固定是1,然后百位和千位上数字从0增长可以增长到多少?显然,增长到32,所以,高位能使得k=2的位置上出现n%100次1,请注意:还有一次是要根据m[k]来确定的;如果m[k]>=1,则是n%100+1,否则就是n%100了。而第二位是对100mod,也就是第k位就是pow(10,k) mod n

2. 一旦第二位出现了1,能保持多长时间呢?显然,如果十位是1,那么10,11,12,。。。,19都能保持住,能保持10次。wait,是不是总是如此,不是的,如果本来第二位是大于1,当然没有问题,比如25,这个时候,10到19都小于25,所以没有问题,十位上的1出现10次;但是如果十位上是1,比如17,这样就不能出现10次了;只能出现10,11,。。。。17,也就是8次。

基于此,给出代码实现:

int func1(unsigned int n)
{
    int count = 0;
    int len = (int)log10((double)n);//总共多少位
    int lenL = -1, lenM = -1, lenR = -1;
    int idxD = -1;
    while( len != -1 )
    {
        lenM = (int)pow(10,(double)len+1);
        lenR = (int)pow(10,(double)len);
        idxD = n%lenM/lenR;//高位能让该位出现几次1
        count += ( n / lenM ) * lenR;
        if( idxD == 1 )//当前位置上是1,要小心
            count += n % lenR + 1;
        else if( idxD > 1 )//大于1,直接加
            count += lenR;
        len--;
    }
    return count;
}

希望对您有帮助!

奖励园豆:5
显龙先生 | 菜鸟二级 |园豆:207 | 2013-08-01 13:43

恩呢。谢谢大神。基本看懂了。

坚持、沉默~ | 园豆:204 (菜鸟二级) | 2013-08-01 17:14
其他回答(1)
0

哈哈,有趣的题目,学习了。

panjk | 园豆:712 (小虾三级) | 2013-08-02 09:03
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册