http://www.lightoj.com/volume_showproblem.php?problem=1140
題意:一個人依次寫下從m到n的數,問你會寫下幾個‘0’
普通的按位DP,預先處理一個數組記錄長度為i的數中首位為j時共有幾個0
統計的時候寫暈了,竟然忘記了某個數本身的0帶來的影響,上次做過一個類似的題目,詢問的是二進位位元上的0 和 1,這次是十進位,差不多的
#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;long long dp[35][10];void init(){ memset(dp,0,sizeof(dp)); for(int i=1;i<=26;i++){ for(int j=0;j<=9;j++) for(int k=0;k<=9;k++) dp[i][j]+=dp[i-1][k]; dp[i][0]+=(long long)pow(10.0,i-1); }}long long calc(long long num){ int a[20],tot=0; long long tmp=num; while(tmp){ a[tot++]=tmp%10; tmp/=10; } long long ans=0; int cnt=0; if(tot==1) return 1; ans=1; for(int i=1;i<tot;i++) { for(int j=1;j<=9;j++) ans+=dp[i][j]; } for(int i=tot-1;i>=0;i--) { if(i==tot-1) { for(int j=1;j<a[i];j++) { ans+=dp[i+1][j]; } } else { for(int j=0;j<a[i];j++) { ans+=dp[i+1][j]; ans+=(long long)cnt*(long long )pow(10.0,i); } } if(a[i]==0) cnt++; } ans+=cnt; return ans;}int main(){ init(); long long m,n; int t,ca=1; scanf("%d",&t); while(t--) { scanf("%lld%lld",&m,&n); printf("Case %d: ",ca++); if(m==0) printf("%lld\n",calc(n)); else { long long a=calc(n),b=calc(m-1); printf("%lld\n",a-b); } } return 0;}