number

Topic description

Someone just learned digital DP, and he suddenly thought about the following questions one day:

Given n, ask how many pairs <x, y> satisfy:

x, y∈[1, n], x < y

           The numbers of [0, 9] appearing in x, y are the same

enter

an integer n (n <= 10 7 )

output

output a number as the answer

sample input

30

Sample output

3

hint

<1, 11> <2, 22> <12, 21>


Ideas:

Violent enumeration from 1 to n, the result is added with the number of the same number of digits that have appeared before this number, and then the number of the same number of digits is added by one;

Use vis[] to store the number of digits of each type.

// vis[i], convert i into a binary number, from left to right
// those bits are 1, then the value of vis[i] is the number of times these numbers have appeared
// for example i = 3 = 0000000110 

// vis[3] is the number of numbers where only 1 and 2 appear

The worst time complexity I think is around 5 * 10^7, but it can be AC.

#include <iostream>
#include <cstring>

using namespace std;

int vis[1<<11];
// vis[i], convert i to binary number, from left to right
// Those bits are 1, then the value of vis[i] is the number of times these numbers have appeared
// eg i = 3 = 0000000110
// vis[3] is only the number of numbers 1 and 2

intmain()
{
    int n, temp, now;
    cin >> n;
    memset(vis, 0, sizeof(vis));
    long long ans = 0;
    for(int i=1; i<=n; i++) {
        temp = i;
        now = 0;
        while(temp > 0) {
            now |= 1<<(temp%10);
            temp /= 10;
        }
        if(vis[now]) {
            // If there is less than i and the same digital type only appears
            // update result
            years += vis[now];
        }
        // update vis[]
        vis[now] ++;
    }
    cout << ans << endl;.
    return 0;
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326076229&siteId=291194637