题目传送门
题意: 给定两个正整数 a a a 和 b b b,求在 [ a , b ] [a,b] [a,b] 中的所有整数中,每个数码(digit)各出现了多少次。
思路: 数位dp模板题,从0到9分别统计每个数位出现次数即可。
代码:
#include<bits/stdc++.h>
#define endl '\n'
#define mp make_pair
#define pb push_back
#define ll long long
#define int long long
#define pii pair<int,int>
#define sz(x) (int)(x).size()
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read()
{
int x=0,f=1;
char ch=gc();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=gc();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=gc();
}
return x*f;
}
using namespace std;
const int N=2e5+50;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
int a[N],len=0;
int f[15][N];
int ans[15][3],now=0;
int dfs(int pos,int st,int limit,int x,int cnt)
{
if(pos==0) return cnt;
if(!limit&&f[pos][cnt]!=-1 && !st) return f[pos][cnt];
int high = limit?a[pos]:9,res=0;
for(int i=0;i<=high;i++)
{
if(st&&i==0) res+=dfs(pos-1,st&&i==0,limit&&i==high,x,cnt);
else res+=dfs(pos-1,st&&i==0,limit&&i==high,x,cnt+(i==x));
}
if(!limit && !st) f[pos][cnt]=res;
return res;
}
void work(int x)
{
len=0;
while(x)
a[++len]=x%10,x/=10;
for(int i=0;i<=9;i++)
{
mem(f,-1);
ans[i][now]=dfs(len,1,1,i,0);
}
now^=1;
}
void solve()
{
int l,r;
cin>>l>>r;
work(l-1);
work(r);
for(int i=0;i<=9;i++)
cout<<ans[i][1]-ans[i][0]<<" ";
cout<<endl;
}
signed main()
{
// int _;
// cin>>_;
// while(_--)
solve();
}