课堂练习之找数字0-N中“1”出现的次数

一、题目与要求

题目:给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数。

要求:1.写一个函数 f(N) ,返回1 到 N 之间出现的“1”的个数。例如 f(12) = 5。

   2.在32位整数范围内,满足条件的“f(N) =N”的最大的N是多少。

二、设计思路

第一种思路:

模10,除10取余,然后寻找规律,

9%10=9、9/10=0;

11%10=1、11/10=1;

15%10=5、15/10=1;

······

然后写了很多,想到如果模10等于0怎么办?等于1怎么办?取余怎么办,判断条件怎么写?

捣鼓了好长时间没有弄明白。

第二种思路(老师上课讲的思路):

f(13)=2+4=6

f(23)=3+10=13

f(33)=4+10=14

f(93)=10+10=20

……

某一位上1的个数与其位上的数字、其高一位上的数字、其低一位上的数字数字有关,最后编程实现如下:

三、源代码

 1 //hanxuedong
 2
 3 #include<iostream.h>
 4 int Count(int n)
 5 {
 6     int count=0;  //对1的个数计数
 7     int now=1;    //N由最低位到最高位此时对应第now位
 8     int l=0;      //第now位的低一位的数字
 9     int nownum=0; //第now位的数字
10     int h=0;      //第now位的高一位的数字
11     if(n<=0)
12     {
13         return 0;
14     }
15     while(n/now!=0)
16     {
17         l=n-(n/now)*now;
18         nownum=(n/now)%10;
19         h=n/(now*10);
20         if(nownum==0)
21         {
22             count+=h*now;
23         }
24         else if(nownum==1)
25         {
26             count+=h*now+l+1;
27         }
28         else
29         {
30             count+=(h+1)*now;
31         }
32         now*=10;
33     }
34     return count;
35 }
36 void main()
37 {
38     int number;
39     cout<<"请输入数字:";
40     cin>>number;
41     cout<<"0--"<<number<<"中1出现的次数为:"<<Count(number)<<endl;
42 }

四、运行结果

五、心得体会

像这一类的题目,找到规律很重要,找到规律就对代码实现以及代码优化就会有很大的帮助,面对不要急着上来就写代码,一定要先在下边动手写写,寻找以下规律。

时间: 2024-10-23 22:24:12

课堂练习之找数字0-N中“1”出现的次数的相关文章

找出一个字符串中最长重复次数的子字符串,并计算其重复次数

原题 找出一个字符串中最长重复次数的子字符串,并计算其重复次数.例如:字符串"abc fghi bc kl abcd lkm abcdefg",并返回"abcd"和2. 我的思路 为了方便表述,我们使用变量src作为原字符串,sub_str作为子字符串. 由于题目要求寻找至少重复2次的最长的子字符串,重点在于最长的子字符串,而不在于重复的最多次数.因此我们可以从长度最长的字符串入手,计算其重复次数.只要重复达到2次,即可返回该字符串. 显然长度最长的子字符串就是原串

程序员面试100题之十:快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值(转)

能否快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值,为了简化起见,我们假设这个数组中肯定存在至少一组符合要求的解. 假如有如下的两个数组,如图所示: 5,6,1,4,7,9,8 给定Sum= 10 1,5,6,7,8,9 给定Sum= 10 分析与解法 这个题目不是很难,也很容易理解.但是要得出高效率的解法,还是需要一番思考的. 解法一 一个直接的解法就是穷举:从数组中任意取出两个数字,计算两者之和是否为给定的数字. 显然其时间复杂度为N(N-1)/2即O(N^2).这个算法很简

18.n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始, 每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。 当一个数字删除后,从被删除数字的下一个继续删除第m个数字。 求出在这个圆圈中剩下的最后一个数字。

转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4263868.html 声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明.谢谢. 题目:n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始, 每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字). 当一个数字

面试题1:找出一个数组中三个只出现一次的数字

version1: 找出一个数组中一个只出现一次的数字,其他数字都出现两次:将所有数字异或,得到的结果即为只出现一次的. version2: 找出一个数组中两个只出现一次的数字,其他数字都出现两次:将所有数字异或,得到的结果即为x=a^b, index为x中第一个为1的位,则a 和b中第index为必然有一个为1,有一个为0.据此将所有数据分为两组,一组的第index为都为1,另一组第index为都为0,第一组数字异或得到a,第二组数字异或得到b. 时间复杂度为o(n),空间复杂度为o(1).

算法题:找出一个数组中依次最大的k个元素

package arithmetic; import java.util.Arrays; /** * 找出一个数组中依次最大的k个元素 * @author SHI */ public class FindMaxFigure { public static void main(String[] args) { int[] a=new int[]{1,5,-1,8,0,2}; System.out.println(Arrays.toString(findBigFigure(a, 3))); } /*

《找出1到正整数N中出现1的次数》

编程思想:依次求出正整数每个位数上出现1的次数,累加即可得到最后想要的结果:而每一位上出现1的个数与和它相邻的其它位数上的数字有关系(以此位置上的数为对称轴,其左边的所有数字作为其最高位,其右边的数字作为其最低位:当然若此位置已处于最低位或最高位,那么它对应的最低位或最高位置0),与它们有一个可求出1的固定的关系式(一个数各个位置上的数分离后,它们都对应着各个位置的基准,例如个位上的数对应的基准为1,以此类推即可),即若此位置上的数字为0,则在此位置上出现1的个数为最高位乘以基准:若为1,则等于

找出十进制数中出现的&#39;&#39;一&#39;&#39;的个数

一.题目要求: 给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数. 要求: 1.写一个函数 f(N) ,返回1 到 N 之间出现的“1”的个数.例如 f(12)  = 5. 2.在32位整数范围内,满足条件的“f(N) =N”的最大的N是多少. 二.解决思路 通过列举几个数进行计算,可以发现函数f(N)规律如下: 1.一位十进制数:当N>=1时,f(N)=1:当N=0时,f(N)= 0; 2.两位十进制数:f(13)=个位出现1的个数+十位出现1的个数=2+4

0~400中1出现了多少次?

今天小菜无意间在社区看到一个讨论:“0~400中1出现了多少次?”. 小菜看到大部分网友给出的算法是基于字符串的处理,思路大致是:把所有数字拼接成一个字符串,然后对字符串进行处理,进而获取出现次数.例如以下代码: 1 /** 2 * 网友版本 3 * 找出"1"出现的次数 4 **/ 5 function numberCount1(n){ 6 var a = []; 7 for (var i = 0; i <= n; i++) { 8 a.push(i); 9 } 10 var

【编程题目】n 个数字(0,1,…,n-1)形成一个圆圈,从数字 0 开始

第 18 题(数组):题目:n 个数字(0,1,…,n-1)形成一个圆圈,从数字 0 开始,每次从这个圆圈中删除第 m 个数字(第一个为当前数字本身,第二个为当前数字的下一个数字).当一个数字删除后,从被删除数字的下一个继续删除第 m 个数字.求出在这个圆圈中剩下的最后一个数字. 思路:看到这道题,直觉是不难,模拟一下过程就好了.我用的是数组来表示的,用first表示当前第一个数字是哪一个数,若删除一个数字则将后面的数字平移到前面. /* 第 18 题(数组): 题目:n 个数字(0,1,…,n