[SCOI2009]windy数

题目描述

windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,

在A和B之间,包括A和B,总共有多少个windy数?

输入格式

包含两个整数,A B。

输出格式

一个整数

输入输出样例

输入 #1
1 10
输出 #1
9
输入 #2
25 50
输出 #2
20

说明/提示

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

 

分析:

一道毒瘤题。。。数据太大。。。所以不难想到数位DP,即对中间的数部分进行讨论。

 

CODE:

 

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 int f[15][15];
 8 long long poww[15];
 9 void pre(){
10     poww[0]=1;
11     for (int i=1;i<=13;i++){
12         poww[i]=poww[i-1]*10;
13     }
14     for (int i=0;i<=10;i++) f[1][i]=1;
15     for (int i=2;i<=12;i++){
16         for(int j=0;j<=10;j++){
17             for (int k=0;k<=9;k++){
18                 if (abs(j-k)>=2) f[i][j]+=f[i-1][k];
19             }
20         } 
21     }
22 }
23 int count(int x){
24     int w=0;
25     int y,pre,ans=0;
26     while (poww[w]<=x) w++;
27     for (int i=1;i<w;i++){
28         for (int j=1;j<=9;j++){
29             ans+=f[i][j];
30         }
31     }
32     y=x/poww[w-1];
33     for (int j=1;j<y;j++) ans+=f[w][j];
34     pre=y;
35     x%=poww[w-1];
36     for (int i=w-1;i>=1;i--){
37         y=x/poww[i-1];
38         for (int j=0;j<y;j++){
39             if (abs(j-pre)>=2) ans+=f[i][j];
40         }
41         if (abs(pre-y)<2) break;
42         pre=y;
43         x%=poww[i-1];
44     }
45     return ans;
46 }
47 int main() {
48     int a,b;
49     cin>>a>>b;
50     pre();
51     cout<<count(b+1)-count(a)<<endl;
52     //system("pause");
53     return 0;
54 }

 

 

 


posted @ 2019-07-25 19:30  Sword_Art_Online  阅读(327)  评论(0编辑  收藏  举报