1591:数字计数
时间限制: 1000 ms 内存限制: 524288 KB
题目描述
原题来自:ZJOI 2010
给定两个正整数 a 和 b,求在 [a,b] 中的所有整数中,每个数码 (digit) 各出现了多少次。
输入格式
仅包含一行两个整数 a,b,含义如上所述。
输出格式
包含一行 10 个整数,分别表示 0∼9 在 [a,b] 中出现了多少次。
样例
样例输入
1 99
样例输出
9 20 20 20 20 20 20 20 20 20
数据范围与提示
30% 的数据中,1≤a≤b≤10^6;
100% 的数据中,1≤a≤b≤10^12。
sol:被初始化搞得很蛋碎,忘了初始化就会挂的相当惨qaq
dp[i][j][k][0,1][0,1]表示前i个位置有k个j的方案数(另两个分别是上界和前导0)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; typedef long long ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } inline void writeln(ll x) { write(x); putchar(' '); return; } #define W(x) write(x),putchar(' ') #define Wl(x) writeln(x) int Num[20]; ll dp[20][10][20][2][2];//前i个位置有k个j的方案数 inline ll dfs(int Weiz,int Shuz,int Ges,bool Shangj,bool Qiand0) { if(dp[Weiz][Shuz][Ges][Shangj][Qiand0]) return dp[Weiz][Shuz][Ges][Shangj][Qiand0]; if(Weiz==1) return (dp[Weiz][Shuz][Ges][Shangj][Qiand0]=Ges); int i,Up=(Shangj)?(Num[Weiz-1]):9; for(i=0;i<=Up;i++) { bool Bo1=(Shangj&&i==Up),Bo2=(Qiand0&&i==0); if(Shuz||(!Bo2)) dp[Weiz][Shuz][Ges][Shangj][Qiand0]+=dfs(Weiz-1,Shuz,Ges+(i==Shuz),Bo1,Bo2); else dp[Weiz][Shuz][Ges][Shangj][Qiand0]+=dfs(Weiz-1,Shuz,Ges,Bo1,Bo2); } return dp[Weiz][Shuz][Ges][Shangj][Qiand0]; } inline ll Solve(ll n,int Shuz) { if(n==0) return 0; *Num=0; // printf("n=%lld ",n); while(n) { Num[++*Num]=n%10; n/=10; } int i; ll ans=0; ans+=dfs(*Num,Shuz,0,0,1); for(i=1;i<Num[*Num];i++) ans+=dfs(*Num,Shuz,(Shuz==i)?1:0,0,0); ans+=dfs(*Num,Shuz,(Shuz==Num[*Num])?1:0,1,0); // printf("ans=%lld ",ans); memset(dp,0,sizeof dp); memset(Num,0,sizeof Num); return ans; } int main() { ll l,r; int i; R(l); R(r); for(i=0;i<9;i++) W(Solve(r,i)-Solve(l-1,i)); Wl(Solve(r,9)-Solve(l-1,9)); return 0; } /* input 1 99 output 9 20 20 20 20 20 20 20 20 20 input 218635 261553 output 17882 18801 69801 26887 26891 26840 18401 16882 17247 17882 */