bzoj1026: [SCOI2009]windy数

Description

windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,在A和B之间,包括A和B,总共有多少个windy数?

Input

包含两个整数,A B。

Output

一个整数。

Sample Input

【输入样例一】
1 10
【输入样例二】
25 50

Sample Output

【输出样例一】
9
【输出样例二】
20

HINT

 

【数据规模和约定】

100%的数据,满足 1 <= A <= B <= 2000000000 。

 
题解:
设f[i][j]表示i位数第一位是j的windy数有多少,注意一下前导0
code:
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 char ch;
 8 bool ok;
 9 void read(int &x){
10     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
11     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
12     if (ok) x=-x;
13 }
14 const int maxl=10;
15 const int maxnum=10;
16 int l,r,f[maxl][maxnum],a[maxl];
17 void init(){
18     for (int i=0;i<=9;i++) f[1][i]=1;
19     for (int i=2;i<=10;i++) for (int j=0;j<=9;j++) for (int k=0;k<=9;k++)
20         if (abs(j-k)>=2) f[i][j]+=f[i-1][k];
21 }
22 int calc(int n){
23     int t=n,len=0,ans=0;
24     memset(a,0,sizeof(a));
25     while (t) a[++len]=t%10,t/=10;
26     for (int i=len;i;i--){
27         for (int j=0;j<a[i];j++) if (i+1>len||abs(j-a[i+1])>=2){
28             if (i==len&&!j){
29                 for (int p=len-1;p;p--) for (int q=1;q<=9;q++) ans+=f[p][q];
30             }
31             else ans+=f[i][j];
32         }
33         if (i+1<=len&&abs(a[i+1]-a[i])<2) break;
34     }
35     return ans;
36 }
37 int main(){
38     init();
39     read(l),read(r);
40     printf("%d\n",calc(r+1)-calc(l));
41     return 0;
42 }

 

你可能感兴趣的:(bzoj1026: [SCOI2009]windy数)