`
leehomjan
  • 浏览: 16963 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

获取1-N之间1出现的个数

阅读更多

前些天,看见一道笔试题。

题目是获取1-N之间1出现的个数,如N为12,则1-12中含有1的数为{1,10,11,12},

那么1的1-12中,1出现的次数为5。

 

解题的思路是分别对出现在个,十,百,千,万...位上的1进行统计。

以N为31608为例

1. 刚开始是对个位上出现的1进行统计

quo = 31608/10 = 3160

bit = 31608%10 = 8

rem = 31608%1 = 0

由此可见从00001-31601总共有3161个数的个位是1 

 

2. 接着对十位上出现的1进行统计

 

quo = 31608/100 = 316

ten = (31608/10)%10 = 0

rem = 31608%10 = 8

由此可见从00010-31519总共有316*10=3160个数的十位是1

 

3. 接着对百位上出现的1进行统计

 

quo = 31608/1000 = 31

hun = (31608/100)%10 = 6

rem = 31608%100 = 8

由此可见从00100-31199总共有32*100=3200个数的百位是1

 

 

4. 接着对千位上出现的1进行统计

 

quo = 31608/10000 = 3

tho = (31608/1000)%10 = 1

rem = 31608%1000 = 608

由此可见从01000-21999+ 31000-31608总共有3*1000+609=3609个数的千位是1

 

 

5. 最后对万位上出现的1进行统计

 

quo = 31608/100000 = 0

tth = (31608/10000)%10 = 3

rem = 31608%10000 = 1608

由此可见从10000-19999 总共有1*10000=10000个数的万位是1

 

根据上面的归纳,可以得出

当前计算的位上的数为0,则

该位上出现1的个数= quo*当前的位数(情况2)

当前计算的位上的数为1,则

该位上出现1的个数=quo*当前的位数+当前计算的位前取最大时剩下的1的个数(情况4)

 

当前计算的位上的数大于1,则

该位上出现1的个数=(quo+1)*当前的位数(情况1,3,5)

 

根据上述想法,做成的代码如下

/*
 * Create at 2014/09/13 By leehomjan
 */
#include <stdio.h>
#include <stdlib.h>

static int count(int orig)
{
    int div = 1; // divisor
    int count = 0;

    int quo = 0; // quotient
    int curr = 0; // current bit
    int rem = 0; // remainder
    // count 1s in bit ten hundred ...
    while (orig / div) {
        rem = orig%div;
        quo = orig/(div*10);
        curr = (orig/div)%10;

        switch (curr) {
            case 0:
                // orig=20200 div=1000
                // there has 2000 1s in thousand bit
                // they are 01[000...999] and 11[000...999]
                count += quo*div;
                break;
            case 1:
                // orig=20165 div=100
                // there has 2066 1s in hundred bit
                // they are [00...19]1[00...99] + 201[00...65]
                count += quo*div + (rem+1);
                break;
            default:
                // orig=20200 div=100
                // there has 2100 1s in hundred bit
                // they are [00...20]1[00...99]
                count += (quo+1)*div;
        }
        div *= 10;
    }
    return count;
}


static inline int get_count(int from, int to)
{ 
    return count(to) - count(from);
}

int main(int argc, char* argv[])
{
    int from = 0;
    int to = 0;
    int rst = 0;

    if (argc == 1 || argc > 3) {
        printf("./count_1_from_M_to_N {<M> <N>|<N>}\n");
        return 1;
    }

    if (argc == 2) {
        to = atoi(argv[1]);
    } else {
        from = atoi(argv[1]);
        to = atoi(argv[2]);
    }
    rst = get_count(from, to);

    printf("There has %d 1s from %d to %d\n", rst, from, to);

    return 0;
}

 

分享到:
评论

相关推荐

    查找m到n之间的k个素数并输出 C++ MFC 实现

    在本项目中,我们主要探讨的是如何利用C++编程语言,结合Microsoft Foundation Classes (MFC)库来实现一个功能,即查找指定范围内(m到n)的前k个素数并将其输出。C++是一种静态类型、编译式、通用的、大小写敏感的...

    猴子选大王

    数组`a`的大小为100,足以容纳编号在1到100之间的猴子。数组元素的初始值被设置为1,表示这些猴子都是大王的候选者。 2. **变量(Variable)**: - `num`:代表猴子的总数。 - `del`:代表每次淘汰的猴子数。 - ...

    国开《数据库基础与应用》形考形考任务1-4答案.pdf

    12. **等值连接**:两个关系的等值连接结果包含的属性个数是两关系属性个数之和减去公共属性的个数,即m+n。 13. **函数依赖的传递性**:如果X→Y和Y→Z成立,那么X→Z也一定成立,这是函数依赖的一个基本性质。 ...

    蓝点被必做的算法经典题java.c/c++

    - `fn = fn-1 * n` - **程序分析**: - 定义一个递归函数来计算阶乘。 - 基本结束条件为n=1时,返回1。 - 递归调用自身,参数减1,直到达到基本结束条件。 #### 程序19: 年龄问题 - **背景**: 五个人依次年龄...

    基于位图的n选m的组合算法实现(C#)

    该方法首先会创建一个长度为n的`BitArray`,然后遍历0到2^n - 1之间的所有整数,将每个整数的二进制表示转化为实际的元素组合。在每次迭代中,通过位运算检查当前位图中1的个数,如果等于m,就将这个组合添加到结果...

    输入两个数,输出在它们之间所有能被3整除的数-C语言代码

    在这个问题中,我们需要编写一段C程序,接收用户输入的两个整数(假设为`num1`和`num2`),然后找到这两个数之间(包含这两个数本身)所有能被3整除的数。为了实现这一功能,我们可以采用以下步骤: 1. **输入处理*...

    从键盘任意输入两个整数,输出两数之间的素数,素数判断用函数实现。 扩展要求:1)程序可以循环执行,判断完一组可以再进行下一组;可以设定一个特殊键退出

    在这个编程任务中,我们需要在C语言环境下实现一个程序,该程序能从用户那里接收两个整数,然后在它们之间找出所有的素数,并显示出来。素数是大于1且只有1和其本身两个正因数的自然数。这里,我们不仅需要实现基本...

    循环练习题

    - 如果`i &lt;= n / 2 + 1`,则打印星号的个数为`2 * i - 1`; - 否则,打印星号的个数为`2 * (n - i) + 1`。 ### 6. 键盘输入一个整数,显示如下的字符图形(N=5时) ``` 1 121 12321 121 1 ``` **知识点:** - ...

    k-means实现图像分割(matlab版)1

    k-means算法的核心是将N*P的矩阵X划分为K个类,使得类内对象之间的距离最大,而类之间的距离最小。k-means算法的计算过程可以分为以下几个步骤: 1. 初始化:选择K个初始聚类中心点 2. 分配:将每个对象分配到离其...

    有史以来最全的c语言笔试题

    - 计算一个字符中1的个数:通过位运算遍历字符的每一位,检查是否为1。 - 字符串反转:遍历字符串,逐字符读取并转换为数字,然后反向构建新的数字。 - 整数转字符串:将整数值转换为字符串表示,通常采用除法和取余...

    列主元高斯消去法解线性方程组的程序(MATLAB版)

    for k=n-1:-1:1 S=b(k); for j=k+1:n S=S-A(k,j)*x(j); % 累加减去其他未知数的影响 end x(k)=S/A(k,k); % 更新未知数 end x % 输出解向量 error=abs(x-ones(n,1)) % 计算误差 ``` - 从最后一个方程开始,逐步...

    专题资料-HOT\树\树状数组

    对于给定数组`a[1..N]`,我们可以定义一个对应于它的树状数组`c[1..N]`,其中`c[i]`表示的是`a[i - 2^k + 1]`至`a[i]`之间元素的和,这里`k`为`i`的二进制表示中最右边0的个数,或者说`2^k`是`i`的二进制表示中最后...

    北航计算机系考研复试上机真题及答1

    解题思路是遍历矩阵,记录每行和每列最左侧和右侧的 1 的位置,遇到 0 时判断其是否位于这些 1 之间,若是则计数加一。 ```c #include #include // ...(代码实现部分省略) ``` 对于这类题目,考生需要注意...

    编程算法练习--没事的时候练练

    = n * (n-1)!。 #### 知识点二十三:折扣计算 - **描述**:根据消费金额计算不同档次的折扣。 - **实现思路**: - 根据消费金额区间设定不同的折扣比例。 - 使用条件语句确定消费金额所属的区间,并计算折扣。 ...

    1线性表1

    数据关系:R1 = {&lt;ai-1, ai&gt; | ai-1, ai ∈ D, i=2,...,n},这表明了元素之间的顺序关系,即每个元素ai紧接在ai-1之后。 线性表的基本操作包括: 1. 初始化线性表:创建一个新的、空的线性表。 2. 销毁线性表:释放...

    C语言练习1[文].pdf

    此练习要求输入两个正整数`m`和`n`,并找出`m`到`n`之间的所有素数,统计素数的个数并求和。素数是只能被1和自身整除的正整数。定义`prime()`函数用于判断一个数是否为素数,如果是素数返回1,否则返回0。在`main()`...

    数论模板精心整编

    \[F_n = F_{n-1} + F_{n-2}\] 其中提到了一个重要的性质——平方和公式。这个公式表达的是第 n 项 Fibonacci 数的平方加上第 n+1 项 Fibonacci 数的平方等于第 n+2 项 Fibonacci 数乘以第 n+3 项 Fibonacci 数减去 ...

    C++I练习题1带答案(06级).doc

    - 当x为-1, 0, 或1时,表达式的值为1(真),其他情况下为0(假)。 2. **调用函数时,希望从提供的实参变量中获取函数的结果,那么对应的形参应该是?** - 如果希望在调用函数后能获取函数处理的结果,并且希望...

Global site tag (gtag.js) - Google Analytics