# 1200_ Statistical issues

Keywords: Algorithm Dynamic Programming

# subject

## Description

The page numbers of a book are encoded sequentially from natural number 1 until natural number n. The page numbers of a book are arranged according to common practice. Each page number does not contain an extra leading number of 0. For example, page 6 is represented by number 6, not 06 or 006. The number counting problem requires that, for a given book, the total page number n be used to calculate how many numbers are used in the total page number of the book 0 ， 1 ， 2 ， ... ， 9 0，1， 2，...，9 0，1，2，...，9.
10-digit integer for the total page number of a given representation n ( 1 ≤ n ≤ 1 0 9 ) n (1 ≤ n ≤ 10^9) n(1 < n < 109). How many numbers are used in all page numbers of a programming calculation book 0 ， 1 ， 2 ， ... ， 9 0，1，2，...，9 0，1，2，...，9.

## Input

There are multiple test cases. Each test case consists of a row containing an integer n representing the total page number of the book.
Enter until no data is available.

## Output

For each test case, a line containing 10 10 10 integers, where the k-th integer represents the number of times the number k-1 is used in the page number, k=1, 2,..., 10. Note: The integers output on each line are separated by a space. You cannot have extra leading and suffix spaces.

11

## Sample Output

1 4 1 1 1 1 1 1 1 1

## Hint

An 11-page book with page numbers of 1 ， 2 ， 3 ， 4 ， 5 ， 6 ， 7 ， 8 ， 9 ， 10 ， 11 1，2，3，4，5，6，7，8，9，10，11 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, of which there is 1 0, 4 1, the numbers 2-9 each.

# Question 1: Violence

It will time out.

#include<iostream>
using namespace std;
int main(){
int n;
while(scanf("%d",&n)!=EOF){
int c={0};
for(int i=1;i<=n;i++){
int tmp=i;
while(tmp){
c[tmp%10]++;
tmp/=10;
}
}
for(int i=0;i<=8;i++){
cout<<c[i]<<" ";
}
cout << c<<endl;
}
return 0;
}


# Solution 2: Dynamic planning

## Analysis

• For one digit D D For D, 1 ∼ D 1\sim D The number of digits used in 1_D is 1 ∼ D 1\sim D 1_D once each.
If D = 9 D=9 D=9, then 0,1,..., 9 in 0 ∼ 9 0\sim 9 The number 0 9 is used once each, and the number of zeros to be removed is 1.

• For two-digit CD s, we consider that C can equal 0.
Then 00, 01,..., 09, 10, 11,... 19,..., (C-1)0,..., (C-1)9, 0 ∼ C − 1 0\sim C-1 0_C_1 is used 10 times as a number of digits, and then 0 ∼ 9 0\sim 9 0_9 is used C times as a number of digits; Then at C0,..., CD, C will be used (D+1) times as ten digits. 0 ∼ D 0\sim D The number of 0_D is used once each.
If D = 99 D=99 D=99, then 0 ∼ 9 0\sim 9 The number 0 9 is used 10 + 10 times, and the number of zeros to be removed is 10 + 1.

• For three-digit ABC
So in 000 , 001 , . . . , 099 , . . . , ( A − 1 ) 00 , . . . , ( A − 1 ) 99 000,001,...,099,...,(A-1)00,...,(A-1)99 000,001,...,099,...,(A−1)00,...,(A−1)99, 0 ∼ A − 1 0\sim A-1 0_A_1 is used 100 times as a 100-digit number, and then 0 ∼ 9 0\sim 9 0_9 will be used as the ten digits 10 × A 10\times A 10 × A times, then 0 ∼ 9 0\sim 9 0_9 will be used as a number of digits 10 × A 10\times A 10 × Again, then A00,A01,..., ABC, then A A A is used as a hundred digits (BC+1) times, and then we can go back to the two-digit thinking for BC.
If D = 999 D=999 D=999, then 0 ∼ 9 0\sim 9 The number 0_9 will be used 100 + 100 + 100 = 10 × 20 + 1 0 2 100+100+100=10\times20+10^2 100+100+100=10 × 20+102 times, the number of zeros to be removed is 100+10+1 times.

Based on this idea, it is easy to find the rule. For n-bit digits 0 to n, if F(n) is set to the number of times each digit from 0 to 9, then F(n) = 10 * F(n-1) + 10^(n-1), where F(1) = 1

We put the result in an array named dp: dp = 0, dp=1, dp=20, dp=300,...

    // 997，len=3
// 000-899
//    0-(num-1) 100th digit 100 times
//    0-9 decimal + digit dp*(num-1+1) times
// 900-997
//    900 digits 97+1 time
//       97
//        00-89
//           0-(num-1) 10-digit 10 times
//           0-9 digits dp*(num-1+1) times
//        90-97
//           9 Ten digits 7+1 time
//           0-(num-1) digits once

#include<iostream>
#include<cmath>
using namespace std;
int main(){
long long dp={0};
for (int i = 1; i < 12;++i) {
dp[i] = 10 * dp[i - 1] + round(pow(10.0, i - 1));
}
long long zero={0};
for (int i = 1; i < 12;++i) {
for (int j = 0; j < i;++j)
zero[i] += round(pow(10.0, j));
}
int n;
while(cin>>n) {
long long c={0};
int num = {0};
int temp = n;
int len = 0;
while(temp) {
++len;
num[len] = temp % 10;
temp /= 10;
}
if(round(pow(10.0,len))-n==1) {
cout << dp[len] - zero[len]<<" ";
for(int i=1;i<=8;i++){
cout<<dp[len]<<" ";
}
cout << dp[len]<<endl;
}
else{
int r = n;
for (int i = len; i > 0;--i) {
r = r % int(round(pow(10.0, i - 1)));
c[num[i]] += (r+1);
for (int j = 0; j < num[i]; ++j){
c[j] += round(pow(10.0, i - 1));
}
for (int k = 0; k <= 9; ++k) {
c[k] += dp[i - 1] * (num[i]);
}
}
c -= zero[len];
for(int i=0;i<=8;i++){
cout<<c[i]<<" ";
}
cout << c<<endl;
}
}
return 0;
}


Posted by FatalError on Fri, 12 Nov 2021 09:14:30 -0800