1833: [ZJOI2010]count 數字計數
阿新 • • 發佈:2018-08-04
。。 沒有 str ret tchar 數字計數 代碼 long long ron
題意:給定兩個正整數a和b,求在[a,b]中的所有整數中,每個數碼(digit)各出現了多少次。
經歷一中午,終於TM做出來了
滿滿的成就。。。
以f[i][j][k]代表長度為i最高位為j數碼k出現幾次
修正:
1、預處理
若最高位j==k 還得加上10的i次冪
2、求
同1,若當前位的上一位跟所求數碼相同
也要加上它乘10的次冪
然而之後
WA
WA
WA
。。。
找到一個坑101
我輸出了111
在2加次冪時,沒有同步減去中間數,導致過大
詳情見代碼QAQ
#include<cstdio> #include<iostream> using namespacestd; #define int long long int f[50][20][20]; int base[20]; int a,b; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) { if(ch==‘-‘) f=-f; ch=getchar(); } while(isdigit(ch)) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } inline void put(int x) { if(x<0) { putchar(‘-‘); x=-x; } if(x>9) put(x/10); putchar(x%10+‘0‘); } inline void init() { for(int i=0;i<=9;i++) f[1][i][i]=1; base[0]=1; for(int i=1;i<=15;i++)base[i]=base[i-1]*10; for(int i=2;i<=14;i++) { for(int j=0;j<=9;j++) for(int l=0;l<=9;l++) for(int k=0;k<=9;k++) f[i][j][l]+=f[i-1][k][l]; for(int k=0;k<=9;k++) f[i][k][k]+=base[i-1]; } } inline int work(int x,int dig) { int ans=0; int len=1; int olinr=x-1; bool flag=true; while(x>=base[len])len++; for(int i=1;i<len;i++) for(int j=1;j<=9;j++) ans+=f[i][j][dig]; int lst=0x7fffffff; for(int i=len;i>=1;i--) { int tp=(x/base[i-1])%10; for(int j=flag;j<tp;j++) ans+=f[i][j][dig]; if(!flag) { if(lst==dig) { ans+=olinr-(dig*base[i])+1; } olinr-=base[i]*lst; //原來放在if裏面,坑死了。。。。 } flag=false; lst=tp; } return ans; } signed main() { a=read(); b=read(); init(); for(int i=0;i<=9;i++) { put(work(b+1,i)-work(a,i)); putchar(‘ ‘); } return 0; }
1833: [ZJOI2010]count 數字計數