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 <= 107)
output
output a number as the answer
sample input
30
Sample output
3
hint
<1, 11> <2, 22> <12, 21>
ideas
The number has a total of 0~9
10 numbers. For the given number, n
we can traverse it once 1~n
. For each number, split the current number into decimal, and then use binary bit pressing to compress it into a state, and mark the current number with an array. The state appeared several times, and finally found
The sum will do.
When the binary bit is pressed, when this bit exists, it isnum|=(1<<i)
code
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
const ll N=1e7+20;
ll vis[15];
ll mp[1025];
int main()
{
ll n,len=0,num=0;
scanf("%lld",&n);
for(ll i=1; i<=n; i++)
{
mem(vis,0);
ll x=i;
while(x)
{
vis[x%10]=1;
x/=10;
}
ll num=0;
for(ll j=0; j<=9; j++)
if(vis[j])
num|=(1<<j);
mp[num]++;
}
ll sum=0;
for(ll i=1; i<=1025; i++)
if(mp[i])
sum+=(mp[i])*(mp[i]-1)/2;
printf("%lld\n",sum);
return 0;
}