PAT Advanced1049 Counting Ones(数学问题)

版权声明:个人学习笔记记录 https://blog.csdn.net/Ratina/article/details/85720211

链接:PAT Advanced1049

The task is simple: given any positive integer N, you are supposed to count the total number of 1’s in the decimal form of the integers from 1 to N. For example, given N being 12, there are five 1’s in 1, 10, 11, and 12.

Input Specification:

Each input file contains one test case which gives the positive N (≤230).

Output Specification:

For each test case, print the number of 1’s in one line.

Sample Input:

12

Sample Output:

5


题意: 给出一个正整数N,求出 [1 , N] 内所有整数一共多少个1。
如N=12,共有5个1(1,10,11,12)。


思路: 对于一个数,求出当某一位为1时,满足条件(≤ N)的数共有多少个,然后每一位求得的和相加,于是转化成了排列组合问题。

假设一个数123t56,求当t=1时可以组成多少个满足条件数(即t=1的情况会在1~123t56出现多少次)。显然要对t的原值进行讨论。

先设t左边的数为L=123,右边的数R=56,t 为第K=3位数。

① t ≥ 2;
当t=1,t 左边有L+1种情况(0 ~ L),t 右边有10(K-1)种情况(0 ~ 10(K-1)-1)。
即左边0 ~ 123,右边 0 ~ 99,均可满足 ≤ N。
则 (L+1) * (10(K-1))即为解。

② t = 1;
a. 当t=1,t 左边为L时,t 右边有R+1种情况(0 ~ R)。(保证满足 ≤ N)
b. 当t=1,t 左边为(0 ~ L-1)时,t 左边有L种情况,t 右边有10(K-1)种情况(0 ~ 10(K-1)-1)。
则(R+1)+ L* (10(K-1))即为解。

③ t = 0;
当t 左边为L时,t 无法取1,(这时候 t 取1就比N大了)所以只能让L-1。
那么当t=1,t 左边为(0 ~ L-1)时,t 左边有L种情况,t 右边有10(K-1)种情况(0 ~ 10(K-1)-1)。
则 L * (10(K-1))即为解。


以下代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{   
	int N,t,L,R=0,K=0,ans=0;
	cin>>N;
	while(N>0)
	{
		t=N%10;
		L=N/10;
		K++;
		if(t==0)
			ans+=L*pow(10,K-1);
		else if(t==1)
			ans+=(R+1)+L*pow(10,K-1);
		else
			ans+=(L+1)*pow(10,K-1);
		R+=t*pow(10,K-1);
		N/=10;
	}
	cout<<ans;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Ratina/article/details/85720211