1. 程式人生 > >1833: [ZJOI2010]count 數字計數

1833: [ZJOI2010]count 數字計數

。。 沒有 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 namespace
std; #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 數字計數