ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数学专题

2022-06-26 10:04:37  阅读:204  来源: 互联网

标签:dots 10 专题 include right 数学 now left


Counting Ones (30)

Link
题意:给定一个数n,求出1~n这n个十进制数中1出现的次数。例如11中1出现了2次,10中出现了1次。
思路:对于n,假设它写成十进制有m位,表示为:
\(a_1 a_2 a_3 \dots a_m\)
其中 \(n=a_1*10^{m-1}+a_2*10^{m-2}+\dots +a_{m-1}*10+a_m\).
那么就对这m位从低到高遍历一遍,每次将这m个数按照当前位划分为三组:left, now, right
第1次:
\(a_ma_{m-1}\dots a_{2}\), \(a_{1}\), \(0\)
第2次:
\(a_ma_{m-1}\dots a_{3}\), \(a_{2}\), \(a_{1}\)
第3次:
\(a_ma_{m-1}\dots a_{4}\), \(a_{3}\), \(a_{2}a_{1}\)
......
第m次:
\(a_m\), \(a_{m-1}\), \(a_{m-2}\dots a_{2}a_{1}\)

这样划分的作用很明显。因为当前位now的值很重要:
例如21031这个数,当前位是0,那么left=21, now=0, right=31。
此时,我们想要找出不超过n的数中now位(即从低到高的第3位,百位)为1的数的个数。
但是现在now位为0,相当于是要将now位增大,那么只好借位了——那就是让left变小。left本来是21,那么我们就取left在[0,20]这个闭区间内的值,这样now位就可以取[0,9]中的任意值了!但是我们只需要1,这样我们就可以计算出now位为1的数的个数。
left确定了,那么right该怎么取值呢?
如果left<21,那么right可以取[0,99]中的任意数;如果left==21,那么right只能取[0,31]中的数,而且此时now必须为0。但是现在我们考虑now==1的情况,因此right可以取[0,99]中的任意数。综上,now位为1的不大于n的数为(20-0+1)*(99-0+1)=2100
在遍历每一位的过程中,我们设置了a来表示当前位处于整个数的什么位置——如果当前位是个位,a就是1;如果当前位是十位,a就是10…以此类推。因此,right部分的取值范围是[0,a-1]这个闭区间,总个数是 a-1-0+1=a

刚才是 now==0 的情况。如果 now==1,那么当left取[0,left-1]时,right可以取[0,a-1];当left取值就是left时,right只能取[0,right],即right+1个数。

如果 now>2,那么left取[0,left],right取[0,a-1]。

AC代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
using namespace std;
int n,ans;
int main() {
	scanf("%d",&n);
	int a=1,left,now,right;
	while(n/a){
		left=n/(a*10),now=(n/a)%10,right=n%a;
		if(now==0) ans+=left*a;
		else if(now==1) ans+=left*a+right+1;
		else ans+=(left+1)*a;
		a*=10;
	}
	printf("%d\n",ans);
	return 0;
}

标签:dots,10,专题,include,right,数学,now,left
来源: https://www.cnblogs.com/preccrep/p/16412997.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有