windy定義了一種windy數。不含前導零且相鄰兩個數字之差至少爲2的正整數被稱爲windy數。spa
windy想知道, 在A和B之間,包括A和B,總共有多少個windy數?code
包含兩個整數,A B。blog
一個整數io
#1class
1 10統計
#2數據
25 50di
#1co
9數字
#2
20
100%的數據,知足 1 ≤ A ≤ B ≤ 2000000000 。
數位dp。
先預處理f[i][j]表示位數爲i,最高位爲j的windy數的個數,f[i][j]=f[i-1][k](|j-k|≥2)
求小於n的wind數的個數,先統計位數小於n的位數的數中windy數的個數,∑f[i][j](i<len) (len爲n的位數)
對於位數和n相同的數,從高位到低位枚舉比n小的最高位
求區間[A,B]中windy數的個數,即爲小於等於B的windy數的個數減去小於A的windy數的個數,而數位dp只能求小於n的知足條件的數的個數,那麼就轉化爲小於B+1的windy數的個數減去小於A的windy數的個數
1 #include <cstdio> 2 const int p10[10]={1,10,100,1000,10000,1e5,1e6,1e7,1e8,1e9}; 3 int A,B,f[15][15],sa,sb,len,dig[15]; 4 int mabs(int x) 5 { 6 return x>0?x:-x; 7 } 8 int dp(int x) 9 { 10 int len,pre,ans=0,y,i,j; 11 for (len=9;x<p10[len];len--); len++; 12 for (i=1;i<len;i++) 13 for (j=1;j<10;j++) 14 ans+=f[i][j]; 15 y=x/p10[len-1]; 16 for (i=1;i<y;i++) ans+=f[len][i]; 17 pre=y; x%=p10[len-1]; 18 for (i=len-1;i>=1;i--) 19 { 20 y=x/p10[i-1]; 21 for (j=0;j<y;j++) 22 if (mabs(j-pre)>=2) 23 ans+=f[i][j]; 24 if (mabs(y-pre)<2) break; 25 pre=y; x%=p10[i-1]; 26 } 27 return ans; 28 } 29 int main() 30 { 31 int i,j,k,x; 32 scanf("%d%d",&A,&B); 33 for (i=0;i<10;i++) f[1][i]=1; 34 for (i=2;i<=10;i++) 35 for (j=0;j<=9;j++) 36 for (k=0;k<=9;k++) 37 if (mabs(j-k)>=2) 38 f[i][j]+=f[i-1][k]; 39 printf("%d",dp(B+1)-dp(A)); 40 return 0; 41 }