课堂练习——找十进制数中数字1的个数

题目要求:

给定一个十进制的正整数,写下从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=6;

          f(23)=个位出现1的个数+十位出现1的个数=3+10=13;

          ......

          f(93)=个位出现1的个数+十位出现1的个数=10+10=20;

  3.三位十进制数:f(123)=个位出现1的个数+十位出现1的个数+百位出现1的个数=13+20+24=57;

  4.f(abcde),计算c位上的1的个数,需要看ab、c、de的情况:

   当c=0时,受高位影响,百位上出现1的个数为:(ab)*100

   当c=1时,受高位和低位影响,百位上出现1的个数为:(ab)*100+((cde)+1)

   当c>1时,受高位影响,百位上出现1的个数为:((ab)+1)*100

二、程序代码

#include "stdafx.h"
#include<iostream.h>
#include "stdlib.h"
int CountNum(int n)
{
    int count=0;
    int factor=1;
    int LowerNum=0;
    int CurNum=0;
    int HigherNum=0;
    while (n/factor!=0)
    {
        LowerNum=n-(n/factor)*factor;
        CurNum=(n/factor)%10;
        HigherNum=n/(factor*10);
        switch (CurNum)
        {
        case 0:
            count=count+HigherNum*factor;
            break;
        case 1:
            count=count+HigherNum*factor + LowerNum +1;
            break;
        default:
            count=count+(HigherNum+1)*factor;
            break;
        }
        factor=factor*10;
    }
    return count;
}

int main()
{
    int num;
    cout<<"请输入数字:\n";
    cin>>num;
    cout<<"\n";
    cout<<num<<"中出现数字1的个数为:\n";
    cout<<CountNum(num)<<endl;
    return 0;
}

三、结果截图

四、心得体会

在课上一开始拿到这个题目,第一反应想的就是找规律,通过举一些例子,特殊数字来观察,但是一开始的时候由于数太多,自己计算的时候出现了错误,很混乱,后来经过老师讲解和同学讨论,找到规律的方向,心平气和的再去计算,这才找出它的规律,像这种找规律的算法,必定要心平气和,不能暴躁,更不能放弃。

时间: 2024-10-06 06:19:40

课堂练习——找十进制数中数字1的个数的相关文章

软件工程课堂练习——找出1-n中1出现的个数

题目:给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数. 要求:写一个函数 f(N) ,返回1 到 N 之间出现的 “1”的个数.例如 f(12)  = 5. 在32位整数范围内,满足条件的“f(N) =N”的最大的N是多少. 一.设计思想 通过归纳法,可以发现: 假设N = abcde,这里a,b,c,d,e分别是十进制数N的各个数位上的数字.如果要计算百位上出现1的次数,将受3方面因素影响:百位上的数字,百位以下(低位)的数字,百位(更高位)以上的数字.

找出十进制数中出现的&#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

一组数中,只有两个数只出现了奇数次,其他所有数都是成对出现的,请找出那两个数

先看一个简单的,一组数中,只有一个数只出现了奇次,其他所有数都是成对出现的,找出出现奇次数的数.对于这个题,我们只需对所有数及逆行异或即可.理论公式: a⊕b=b⊕a a⊕0=a a⊕b⊕b=a a⊕(b⊕c)=(a⊕b)⊕c 代码: #include <stdio.h> #include <stdlib.h> int main() { int arr[] = { 1, 2, 3, 4, 1, 2, 3 }; int ret = 0; int len = sizeof(arr) /

十进制数中1的个数

一.题目: 给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数.要求: 1.写一个函数 f(N) ,返回1 到 N 之间出现的“1”的个数.例如 f(12)  = 5.2.在32位整数范围内,满足条件的“f(N) =N”的最大的N是多少. 二.思路: 这道题偏向数学的推理,其根本在于找规律,而规律则在于将所给的数进行分解,分成个十百千等位数的个体,再从每个中寻找规律.通过整理,每一位有多少个1只与其前后两位有关系,具体算法程序如下: 三.源程序 1 #inclu

找出1-100中缺失的两个数

题目:有一个数组 int array[100]:本来应该存放的数为1~100,但是有两个数据a,b丢失了,值变成了0.问如何找出丢失的那两个数?附带条件不能开辟额外的空间. 解题思路:常见的两种解法有:1.计算a+b和a*b的值,然后在解方程求解(但是这样会使得中间某个变量过大).2.使用bit位来标记.占用13个字节.第二种方法使用了额外空间,第一种可能会造成整型溢出.这里考虑转化为熟悉的方法.数组array[100],其下标正好为0-99,能不能利用上数组下标求解呢?答案是肯定的.这里将数组

从一堆数中随机取出几个数

int c = keywTab.Rows.Count; if (c > 3) { int[] num = new int[4]; Random r = new Random(); for (int i = 0; i < num.Length; i++) { num[i] = r.Next(c); for (int j = 0; j < i; j++) { if (num[i] != 0 && num[i] != num[j]) i++; i--; } } int x =

在n个任意不相同的数中,输出r个数的组合,并且n和r由键盘输入。

主要是运用递归的思想,函数主要两个参数,point是上一次取到的位置,picked主要记录在数组b中所取的元素的个数,函数的每一轮递归都会取一个数.   1 package pack; 2 import java.util.*; 3 4 public class demo_1 { 5 static int r,n; 6 static int a[]=new int [100]; 7 static int b[]=new int[100]; 8 static void f(int point,in

分别统计一句话中数字和字母个数(以“?”结束)【C】

#include<stdio.h>int main(){    char c;    int s1,s2;    s1=0;    s2=0;    scanf("%c",&c);    while(c!='?')    {        if(c>='a'&&c<='z'||c>='A'&&c<='Z')        {          s1++;        }        else        

找出一组数中只出现一次的两个数,其他所有数都是成对出现的

题目: 给一组数,只有两个数只出现了一次,其他所有数都是成对出现的.怎么找出这两个数.编写函数实现. 题目分析: 上次介绍了,对于一组数中只有一个数只出现一次,其他所有数都是成对出现的,我们采用了对全部数组元素进行异或,但是对于找出两个出现一次的数应该怎么解决呢?先对所有的元素进行异或,则结果为两个出现一次的数的异或结果,然后将结果转换为二进制,找出二进制数中的第一个1,然后根据这个1的判断条件进行分组,分为两组,分别对两个组的元素进行全部异或,则就找出两个不同的数. 例如:数组中的元素为下面这