题目描述
​ 试计算在区间 1 到 n的所有整数中,数字x (0≤x≤9)共出现了多少次?

​ 例如,在 1到11中,即在 1,2,3,4,5,6,7,8,9,10,11 中,数字 1 出现了 4 次。

输入
​ 2个整数n, x,之间用一个空格隔开。

输出
​ 1个整数,表示x出现的次数。

分析

最简单的暴力循环,非常耗时:

优化方案:
可以逐位分析,比如输入6573,5时。逐位分析如下:(k为从右往左数第几位)

  1. k=0时,???5 ,前三位可取范围为:[0,656] 共657种;高位恰好为657
  2. k=1时,??5? ,前两位可取范围为:[0,65] 66种;最后一位可取范围为:[0,9]共10种,所以共计660种
  3. k=2时,?5??,
    3.1 前1位取范围:[0,5],后两位可取范围为:[0~99],可取范围为 6 ∗ 1 0 2 = 600 6*10^2=600 6∗102=600种;
    3.2 前1位取6时,即65??,后两位可取范围位[0~73]共74种
    3.3 综上,此时可取范围为674种
  4. k=3时,5???,后三位可取 1 0 3 = 1000 10^3=1000 103=1000种
  5. 所以最终结果为:657+660+674+1000=2991种

从上述推导可以尝试推出一般规律,高位取值范围(当前位左边的数字)取决于当前位(cur)和输入x的相对大小,当输入n为6573时,以计算十位为例,cur=7(十位数字),此时cur左边高位 high=65,k=1(右边第一位,从0开始)

  1. cur<x时;假设x=8,??8?, 高位只能取[0,64],共65种,即high种,得到: a n s = ( h i g h ) ∗ 1 0 k = 650 ans=(high)∗10^k=650 ans=(high)∗10k=650
  2. cur>x时;假设x=5, ??5? , 高位可取[0,65],共66种,即high+1种, 低位10种,得到: a n s = ( h i g h + 1 ) ∗ 1 0 k = 660 ans=(high+1)∗10^k=660 ans=(high+1)∗10k=660
  3. cur==x时;假设x=7, ??7?, 此时分两种计算: 高位取 [0,64],低位取0~9;高位取65,即 657?,低位取[0,7]共8种。得到: a n s = h i g h ∗ 1 0 k + n ans=high*10^k+n ans=high∗10k+n% 1 0 k ( 低 位 ) + 1 = 65 ∗ 10 + 1 ∗ ( 7 + 1 ) = 658 10^k(低位)+1=65*10+1*(7+1)=658 10k(低位)+1=65∗10+1∗(7+1)=658
  4. 特别的,考虑输入x为0的情况, ??0?,按照情形2(cur>x)之前分析,高位取[0,65]共66种,实际上此处不能取0,如果取0则变成了000?,去掉高位的0最后取到的数为0 ~ 9,很明显 1 ~ 9不包含0不符合题意,数字0虽然包含0,但题目要求范围是[1,n],所以此时高位可取范围为[1,65]共65种, 即需要在上面的情况下-1;

解决方案

备注:如果理解了上面的分析过程,那么不用看代码注释。

#include <stdio.h>
#include <math.h>
int func(int n,int x){int ans=0;int tmp=n;  //备份n,变更tmp不改变n;int high,mi,cur,k=0;//k代表从右往左数第几位,从0开始数while(tmp){cur=tmp%10; //cur 代表当前位数,从个位开始tmp=tmp/10; // tmp为商,比如最开始tmp为32487,当k=1时,tmp=324,cur=8;//分三种情况讨论(下例均讨论计算十位的情况,即k=1)://1. 当cur<x时:输入n=32487,x=9;当k=1时,tmp=324,cur=8,要想十位为9,前面三个数的范围只能为[0,323]共324种,个位数为0-9共十种, ==》 tmp*10^k=3240种//2. 当cur>x时:输入n=32487,x=7;当k=1时,tmp=324,cur=8,要想十位为7,前面三个数的范围为[0,324]共325种,即tmp+1种;个位同上十种情况,==》 (tmp+1)*10^k=3250//3. 当cur==x时:输入n=32487,x=8;当k=1时,tmp=324,cur=8,要想十位为8,前面三个数取[0,323]时,得到 tmp*10^k=3240种,当前三位数为324时,即3248?,cur右边的最大值为7,共8种情况(0~7),==》 tmp*10^k+n%(10^k)=3247种;//4. 考虑特殊情况(x输入0时),当n=32487,x=0;当k=1,tmp=324,cur=8,按照前面的讨论2,cur>x,那么 ???0?,前三位取值范围应该为[0,324]共325种,实际上此时不能取0,如果取0,则变成了0000?,去掉首位的0,得到的结果是0~9,1~9明显不包含0不符合题意,0虽然包含0,但题目要求是[1,n],故舍去。即此时前三位取值只能是[1,324]共324种情况high=tmp; //不同情况需要的tmp不同,但是tmp作为最外层循环条件,不应该改变,所以另外给一个变量来计算if(x==0) high--;if(cur>x) high++;mi=pow(10,k); //pow默认返回double,可以使用(int)强制转换ans+=high*mi;if(cur==x) ans+=n%mi+1;  k++;}return ans;
}
int main(){int n,x;scanf("%d%d",&n,&x);printf("%d\n",func(n,x));return 0;
}

效率明显好于暴力循环

小结

这类问题咋一看很复杂,其实只要静下心来仔细分析,也不是什么难题。就是高中数学的基本组合思维。工作中太久不用,生疏了而已

计数问题:1~n中x出现了多少次?相关推荐

  1. GNU Make 使用手册(于凤昌中译版)

    GNU Make 使用手册(中译版) 翻译:于凤昌 GNU make Version 3.79 April 2000 Richard M. Stallman and Roland McGrath 1 ...

  2. P1446 [HNOI2008]Cards

    P1446 [HNOI2008]Cards 题意: 有n张牌,染三种颜色,每种颜色规定数目,给出m种不同的洗牌方法.两种染色方法相同当且仅当其中一种可以通过任意的洗牌法(即可以使用多种洗牌法,而每种方 ...

  3. Sql Hacks 阅读感悟——数值处理

    SQL基础:<SQL HACKS>第5章--数值处理,总共列举了17个tips,计算结果集的乘积.计算累加和.包含Join遗忘的行等,下述为我对这17个tips的评析. #24 计算结果集 ...

  4. 面试:第十二章:所有总结

    Java基础 java基本类型哪些,所占字节 byte :1个字节 short :2个字节 char :2个字节 int :4个字节 long :8个字节 float :4个字节 double :8个 ...

  5. linux内核分析(转自某位大哥网上的笔记)

    启动 当PC启动时,Intel系列的CPU首先进入的是实模式,并开始执行位于地址0xFFFF0处的代码,也就是ROM-BIOS起始位置的代码.BIOS先进行一系列的系统自检,然后初始化位于地址0的中断 ...

  6. F(n)完全覆盖中的计数问题

    完全覆盖中的计数问题 山西省原平一中 任所怀 这几天阅读周沛耕老师主编的<数学 兴趣与创造力>一书,读到"完全覆盖中的计数问题"这一节,感觉有点意思.于是自已试着做一个 ...

  7. hdu 5119 (类似于划分数的状态定义) (DP中的计数问题)

    题目描述:求n个数中异或值大于m的方案数有多少个? 设状态f[i][j]代表前i个数异或值为j的方案数有f[i][j]种,那么对于j来说要么选第i个数与前面的i-1个数中的某些数构成j,f[i-1][ ...

  8. 《算法竞赛中的初等数论》(四)正文 0x40反演(ACM / OI / MO)(十五万字符数论书)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 写在最前面:本文部分内容来自网上各大博客或是各类图书,由我个人整理,增加些许见解,仅做学习交流使用,无 ...

  9. 在C/C++中嵌入Python

    在C/C++中嵌入Python也比较简单,首先需要在VC中添加Python的include文件目录和lib文件目录: VC6.0下,打开tools->options->directorie ...

最新文章

  1. 提示语_交通安全提示语
  2. 【实战】MATLAB+神经网络+MNIST
  3. pixel 解锁_如何在Google Pixel 4和Pixel 4 XL上禁用面部解锁
  4. 汇编为什么分段执行总是执行不了_为什么我的计划总是执行不了?这里有你要的答案...
  5. 2021云栖大会开源引力峰会发布的战略合作,Grafana服务到底是什么?
  6. mysql5.7.19不好用_Mysql 5.7.19 免安装版遇到的坑(收藏)
  7. springboot mysql事物_SpringBoot事务详细简介
  8. c++调用python原理_C++调用Python浅析
  9. 一小时学会用Python Socket 开发可并发的FTP服务器
  10. MSDN Visual系列:用WSSv3中的SPGridView控件来显示数据
  11. 余额宝宣布开放 中欧基金首批入驻
  12. HTML5权威指南 6.多媒体相关API
  13. Eclipse下搭建安卓开发环境(初步)
  14. html导航栏的渐变效果,html+css+js实现导航栏滚动渐变效果
  15. Windows命令行计算文件MD5
  16. 计算机网络原理——传输层TCP协议的十个重要特性之保证可靠性的机制(确认应答和超时重传)
  17. Vue中设置浏览器标签栏图标以及title
  18. 让POW的共识机制不再成为公链系统吞吐率的瓶颈 | Conflux CTO伍鸣
  19. 【Nape教程】Nape刚体碰撞检测
  20. Geek 设计师们疯狂的桌面

热门文章

  1. C++函数模板和模板函数、类模板和模板类
  2. [PyQt5]基本控件24 - 时间日期编辑框QDateTimeEdit
  3. 我是一个*** (九)
  4. 坠落的蚂蚁【思维/模拟】
  5. 电脑重装系统-利用PE系统盘安装
  6. 【转】Ceph对象存储(rgw)的IPv6环境配置
  7. 打开用友总账时提示“该产品没有安装,无法使用”
  8. RKMPP库快速上手--(二)MPP关键配置
  9. thinkPHP3.2.3使用163邮箱发送邮件
  10. dcloud进行android离线打包 需要继承io.dcloud.application.DCloudApplication的问题