几个一?

一、题目

  给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数。 要求: 写一个函数 f(N) ,返回1 到 N 之间出现的 “1”的个数。例如 f(12) = 5。 在32位整数范围内,满足条件的“f(N) =N”的最大的N是多少。

二、设计思路

  思路来自于张欢龙的启发,就是将一个整数拆分,一位一位地求出“1”的个数,如451就是:

  45*1+1*1

+4*10+1*10

+0*100+1*100。

  先考虑个位,个位上数字0~9,总共出现过45个0~9,一个0~9有一个1,所以位45*1,而45个0~9外还有一个0~1,这时要再加上一个1;接着十位,每100个数里面均有*10到*19这10个出现1的数,所以十位也是0~9,但这里面的1要乘以10,4个0~9还多余一个0~5,所以也要加1,且乘以10;以此类推......

  如果某一位上是1,是不是情况就不一样了?如111,111情况如下:

 11*1+0+1

+1*10+1+1

+0*100+11+1

...

+(m前面的十进制值*10m+m后面的十进制值+1(后面的值全为0的情况))

  就是当1出现时,这个多余的1的个数就为这一位后面的值。

  求f(N)=N的情况时,从2147483647开始向下逐一计算,时间过长,随便选了一个数即214748364,用前面的算法求出结果发现f(N)>N,所以正确的N一定比这个数小,所以从这开始计算。

三、源代码

 1 //刘双渤,2015年6月3日
 2 //输入一个整数,输出出现1的个数
 3 #include <iostream>
 4 using namespace std;
 5 
 6 void main()
 7 {
 8     long num,rem,t,S;          //输入值,余数,十的倍数,一的总数
 9     long numS;
10     cout<<"请输入一个整数:"<<endl;
11     cin>>num;
12 
13     t = 1;
14     S = 0;
15     numS = num;
16     while(numS != 0)
17     {
18         rem = numS % 10;
19         numS = numS / 10;
20         if(numS != 0)
21         {
22             S += numS * t;
23         }
24         
25         if(rem > 1)
26         {
27             S += t;
28         }
29         else if(rem == 1)
30         {
31             S = S + num -numS * t* 10 - rem * t + 1;
32         }
33         t = t * 10;
34     }
35     cout<<"出现的“1”的个数为:"<<endl;
36     cout<<S<<endl;
37 
38 
39     for(long i = 214748364;i >= -214748364;i--)
40     {
41         t = 1;
42         S = 0;
43         numS = i;
44         while(numS != 0)
45         {
46             rem = numS % 10;
47             numS = numS / 10;
48             if(numS != 0)
49             {
50                 S += numS * t;
51             }
52             if(rem > 1)
53             {
54                 S += t;
55             }
56             else if(rem == 1)
57             {
58                 S = S + i -numS * t* 10 - rem * t + 1;
59             }
60             t = t * 10;
61         }
62         if(S == i)
63             break;
64     }
65     cout<<"满足条件的“f(N) =N”的最大的N是:"<<S<<endl;
66 }
View Code

四、实验结果

  

五、实验总结

 刚看到这个题目时,感觉很简单,然后就开始一个个值去算,用归纳法找规律,可越写发现情况越复杂,有点难!课上有人展示思路,下课再想,就有慢慢清晰,简单了起来。方法很多,却很需要这灵光一点,才能通透。

转载于:https://www.cnblogs.com/little-clever/p/4550579.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值