【题目】输入一个整数n,求从1到n这n个正数中,x出现的次数。x是1,2,...,9中任意一个。

例如:输入12,x=1,出现一的数字有1,10,11,12共有5个1,则输出5。

输入12,x=2,出现一的数字有2,12共有2个2,则输出2。

输入12,x=3,出现一的数字有3共有1个3,则输出1。

【分析】

网络上流传很广的一道题和它很像:输入一个整数n,求从1到n这n个正数中,1出现的次数。例如:输入12,出现一的数字有1,10,11,12共有5个1,则输出5。

此题是笔者研究了网络上的那道以后自己搞的扩展。

简单方法不再赘述,这里只讨论扩展算法。思路和网络上那道一样,分别计算各位、十位、百位、千位、...上每一位中可能出现的x的个数,然后相加即可。

对于x=1的情况,推荐http://www.cnblogs.com/python27/archive/2011/12/14/2288205.html给出了规律分析,一下转引了该文章的分析部分:

=================================================================================

首先,我们有如下比较容易得到的结论,0-9中1的个数是1个,0-99中十位(10-19)上1的个数是10,0-999中百位上(100-199)上1的个数是100,以此类推。为什么需要这些数字,我们经过简单罗列,很容易发现:个位上1的个数,实际上和这个数字包含多少个10有关,因为对于个位来说,总是从0-9循环,十位上1的个数,实际上和这个数字包含多少个100有关,因为每包含1个100,就有0-99的循环,而0-99中十位上的1是10个;那么关系究竟是什么呢?我们看下面的例子来理解:

  对于数字123:

  123/10=12,包含12个10,每个10包含1个1(个位1)所以个位共包含12*1=12个1;余数的情况后面单独讨论;

  123/100(或者12/10)=1,包含1个100,每个100包含10个1(十位1),所以十位共包含1*10=10个1;余数的情况后面单独讨论;

  123/1000(或者1/10)=0,包含0个1000,每个1000包含100个1(百位1),所以百位共包含0*100=0个1;余数的情况后面单独讨论;

  现在考虑余数的两种情况:

  (1)余数大于1的情况:

  数个位时,余数3大于1;所以个位上1的个数要+1;

  数十位时,余数2大于1;因为增加了100-120之间(10-19)的数字即110-119,所以十位上1的个数要+10;

  (2)余数等于1的情况:

  数百位时,余数等于1;我们应该增加100-123这24个数字中百位上的1,共计24个;

  在上面的计算中我们发现123/1000=0包含0个1000,所以百位包含0*100个1,这是常规的情况,实际上由于百位为1,从100到n(123)中还应增加:123-100+1个1.

总结上面的情况:就是对于每一位(个位,十位,百位),我们计算他们“通常”情况下(即该数字包含多少个10,100,1000乘以对应的1的个数)包含的1的个数+该位上余数大于1(等于1)的情况下包含的1的个数 = 该位上1的总个数,所有的位遍历,求和,就好了。

=================================================================================

笔者自己再次总结一下:每一位上1的个数都是由它的高位和自己决定的。123太简单,如果拿3456来看:

第0位(个位):3456/10 + (6>1) ? 1 : 0 = 345 + 1 = 346

第1位(十位):(3456/100) * 10 + (5 > 1 ? 10 : (5 == 1 ? 6 + 1 : 0)) = 340 + 10 = 350

第2位(百位):(3456/1000) * 100 + (4 > 1 ? 100 : (4 == 1 ? 56 + 1 : 0)) = 300 + 100 = 400

第3位(千位):(3456/10000) * 1000 + (3 > 1 ? 1000 : (3 == 1 ? 456 + 1 : 0)) = 1000

346 + 350 + 400 + 1000 = 2096

通过以上例子可以总结出通向公式:

对于给定的正整数value,v[i]代表第i位上的数字,a[i]代表第i位上x出现的次数,c[i]代表第i位后面的数字组成的整数。i的范围:0到最高位-1,假如给定的value为2345,则i的取值范围:0-3,当i=0时,c[i]=0。那么有:

a[i] = (value / (10 ^ (i+1))) * (10 ^ i) + (v[i] > x ? (10 ^ i) : (v[i] == x ? c[i] + 1 : 0))

将这个公式套用到3456上就可以明白为什么上面用复杂的公式计算各位上1的个数了。

/**
return n^p;
*/
int myPower(int n, int p) {
int ret = 1;
while (p>0) {
ret = ret * n;
p--;
}
return ret;
}
/**
* c[i] = value % (10^i)
* a[i] stands for the number of n occurs in ith (i>=0)
* a[i] = (value / (10 ^ (i+1))) * (10 ^ i) + (v[i] > n ? (10 ^ i) : (v[i] == n ? c[i] + 1 : 0))
*/
int countIthN(int value, int i, int n) {
if (value < 0) {
return -1;
}
if (i == 0) {
return value / 10 + ((value % 10) >= n ? 1 : 0);
}
int pi = myPower(10, i);
int pi_1 = myPower(10, i+1);
int ci = value % pi;
int vi = (value / pi) % 10;
return value / pi_1 * pi + (vi > n ? pi : (vi == n ? (ci + 1) : 0));
}
int countN(int value, int n) {
int ret = 0;
for (int i = 0; value / myPower(10, i); i++) {
ret += countIthN(value, i, n);
}
return ret;
}

1到n的正整数x出现的次数相关推荐

  1. AES算法相关数学知识 - 素域学习

    在AES算法中的MixColumn层中会用到伽罗瓦域中的乘法运算,而伽罗瓦域的运算涉及一些数学知识如下: 素域 有限域有时也称伽罗瓦域,它指的是由有限个元素组成的集合,在这个集合内可以执行加.减.乘和 ...

  2. [Go] 正则表达式 示例

    package mainimport "bytes" import "fmt" import "regexp"func main() {// ...

  3. [Wannafly挑战赛2D-Delete]最短路

    [Wannafly挑战赛2D-Delete]最短路 题目描述 给定一张 n 个点,m 条边的带权有向无环图,同时给定起点 S 和终点 T ,一共有 q 个询问,每次询问删掉某个点和所有与它相连的边之后 ...

  4. Caffe-SSD相关源码说明和调试记录

    1      对Blob的理解及其操作: Blob是一个四维的数组.维度从高到低分别是: (num_,channels_,height_,width_) 对于图像数据来说就是:图片个数,彩色通道个数, ...

  5. 【HDU - 4345 】Permutation(DP)

    BUPT2017 wintertraining(15) #8F 题意 1到n的排列,经过几次置换(也是一个排列)回到原来的排列,就是循环了. 现在给n(<=1000),求循环周期的所有可能数. ...

  6. [Java] 蓝桥杯ADV-158 算法提高 新建Microsoft Word文档

    问题描述 L正在出题,新建了一个word文档,想不好取什么名字,身旁一人惊问:"你出的题目叫<新建Microsoft Word文档>吗?",L大喜,一拍桌子,说:&qu ...

  7. 蓝桥杯 ADV-158 算法提高 新建Microsoft Word文档

    问题描述 L正在出题,新建了一个word文档,想不好取什么名字,身旁一人惊问:"你出的题目叫<新建Microsoft Word文档>吗?",L大喜,一拍桌子,说:&qu ...

  8. 牛客练习赛68 B.牛牛的算术

    牛客练习赛68 B.牛牛的算术 题目链接 题目描述 牛牛最近学习了取模是什么 于是他看到了下面这一道题: 多次询问:每次询问包含一个正整数 n 要求你输出下列结果 ∏i=1n∑j=1i∑k=1ji×j ...

  9. css 超出文字头尾相接滚动_【转载】CSS3 ——文本超出设置 超出显示...与跑马灯效果...

    桌面平台的开发中,内容超出设定区域的大小时,我们常用的操作有三种,一个是显示,一个是隐藏,一个是出现滚动条. 在手机平台的开发中,我们常用的操作也有三种,第一是隐藏,第二是显示"...&qu ...

最新文章

  1. 计算机网络体系结构作业题整理-第十章答案
  2. 我的Blog页面设计
  3. 蓝桥杯2018初赛-哪天返回-模拟
  4. openMP学习笔记(一)
  5. 论文阅读 - CRNN
  6. MyEclipse的自动补全功能:输入@或者.没提示
  7. VALSE 2020 线上大会简明日程发布(7月31日-8月5日)
  8. 利用XSS盗取cookies
  9. weex android 交互,weex项目接入到Android studio中
  10. properties 配置回车_非常全面的讲解SpringCloud中Zuul网关原理及其配置,看它就够了! - 风平浪静如码
  11. 计算机维修需要工具,小200个电脑维护工具,都能去开个维修店了
  12. oracle 时间转换 1970,oracle 中将unix/linux时间戳进行转换(转)
  13. worldpress或zblog安装时建立数据库连接时出错
  14. 超多惊喜!苹果 iPhone8 最新渲染图曝光
  15. Lua:协程,coroutine.create,coroutine.resume, coroutine.yield
  16. 最优停止找停车位问题的最简单解释
  17. 此nbsp;夜nbsp;无nbsp;眠
  18. 存算分离后,VxRail动态计算节点构建虚拟化更给力
  19. 加密解密--换行符作祟
  20. [Android答答答]Handler是什么?

热门文章

  1. 线性代数复习 第二章 矩阵
  2. CAD制图软件使用心得(第五期)
  3. Linux 中指定使用的GPU
  4. thinkPython2考试周吐血整理(第一章到第九章)
  5. 爬梯:Maven全解析
  6. 荣耀50系列发布半年,60又来,考虑入手吗?
  7. 个税新政来临,HR如何10秒速算薪酬?
  8. 6天百度第一3321链轮模型大曝光
  9. 计算机考证报名有几天
  10. Intel CPU 型号介绍