1. 程式人生 > 其它 >PAT 1049 Counting Ones (30 分)

PAT 1049 Counting Ones (30 分)

技術標籤:PAT演算法

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 (≤2

​30
​​ ).

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

Sample Input:

12

Sample Output:

5

分析:
一、首先想到暴力求解,幾分鐘得22分,很值

二、這是一個數學問題,計數1的個數,可以計算每數位(個位、十位…)出現1的次數,相當於一個排列組合題,從個位開始計算,例(80132這個數)分情況:

1、當計算千位時,該數為0,則固定該位為1的情況時,出現的次數由該位所在的數位該位左邊的數決定,比如:71000,71001…71999。一共有1000種,而左邊數為0-7時千位可以出現1,所以組合一波,出現8 * 1000種,所以當該位數為0時,該位出現1的次數等於左邊的數(8)乘以該位所在的數位(1000)

2、當計算百位時,該數為1,和上面思路一樣,只是多了
當數到80100-80132的情況;所以該位出現一的次數為左邊的數(80)乘以該位所在的數位(100)+右邊的數(32)+ 1

3、當計算百位時,該數為3,也和上面思路相似;只是和情況1計算左邊數多了1,這回左邊的數為0-801,而不是0-701;因為,該數大於了1,已經把8011*的情況佔完,所以該數位出現1的個數為(左邊的數(801)+ 1) 數位(10)

最後依次按上面3種情況計算,加上每位出現1的次數就OK了

我的程式碼:

#include<cstdio>
int main()
{
    int n,cnt = 0,right = 0,a = 1;
scanf("%d",&n); while (n != 0) { if (n % 10 == 0) cnt += n / 10 * a; else if (n % 10 == 1) cnt += n / 10 * a + right + 1; else cnt += (n / 10 + 1) * a; right = right + n % 10 * a; n = n / 10; a *= 10; } printf("%d",cnt); return 0; }