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.

Sample Input

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[10]={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[9]<<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] = 0, dp[1]=1, dp[2]=20, dp[3]=300,...

    // 997,len=3
    // 000-899
    //    0-(num[3]-1) 100th digit 100 times
    //    0-9 decimal + digit dp[2]*(num[3]-1+1) times
    // 900-997
    //    900 digits 97+1 time
    //       97
    //        00-89
    //           0-(num[2]-1) 10-digit 10 times
    //           0-9 digits dp[1]*(num[2]-1+1) times
    //        90-97
    //           9 Ten digits 7+1 time
    //           0-(num[1]-1) digits once   
#include<iostream>
#include<cmath>
using namespace std;
int main(){
    long long dp[12]={0};
    for (int i = 1; i < 12;++i) {
        dp[i] = 10 * dp[i - 1] + round(pow(10.0, i - 1));
    }
    long long zero[12]={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[10]={0};
        int num[12] = {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[0] -= zero[len];
            for(int i=0;i<=8;i++){
                cout<<c[i]<<" ";
            }
            cout << c[9]<<endl;
        }
    }
    return 0;
}

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