[bzoj1026][SCOI2009]windy数 (数位dp)

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 。

分析

     思路没有什么难度……但是……难道每道数位dp的细节都这么多吗!TAT

 

ExpandedBlockStart.gif
 1  /* *************************************************************
 2      Problem: 1026
 3      User: AsmDef
 4      Language: C++
 5      Result: Accepted
 6      Time:0 ms
 7      Memory:804 kb
 8  *************************************************************** */
 9  
10  /* ********************************************************************* */
11  /* *********************By Asm.Def-Wu Jiaxin**************************** */
12  /* ********************************************************************* */
13 #include <cstdio>
14 #include <cstring>
15 #include <cstdlib>
16 #include <ctime>
17 #include <cctype>
18 #include <algorithm>
19 #include <cmath>
20  using  namespace std;
21 typedef  long  long LL;
22  #define SetFile(x) ( freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout) )
23  #define getc() getchar()
24 template< class T>inline  void getd(T &x){
25      char ch = getc(); bool neg =  false;
26      while(!isdigit(ch) && ch !=  ' - ')ch = getc();
27      if(ch ==  ' - ')ch = getc(), neg =  true;
28     x = ch -  ' 0 ';
29      while(isdigit(ch = getc()))x = x *  10 -  ' 0 ' + ch;
30      if(neg)x = -x;
31 }
32  
33  /* ********************************************************************* */
34  int F[ 12][ 13], S[ 12];
35 inline  void init(){
36      int i, j, t;
37     S[ 0] =  10;
38      for(i =  1;i <=  10;++i)F[ 0][i] =  1;
39      for(i =  1;i <=  10;++i){
40          for(j =  1;j <=  10;++j)S[i] += F[i][j] = S[i- 1] - F[i- 1][j] - F[i- 1][j- 1] - F[i- 1][j+ 1];
41     }
42 }
43  
44 inline  int calc( int x){
45      if(!x) return  0;
46      int X[ 13], len =  0, i, j, t =  0, ans =  0;
47      while(x){X[len++] = x %  10;x /=  10;}X[len] = - 1;
48      for(i = len- 1;i >=  0;--i){
49          for(j =  1;j <= X[i];++j){
50              if(abs(j-t) <  2) continue;
51             ans += F[i][j];
52         }
53          if(abs(X[i+ 1]-X[i]) <  2) break;
54          if(!i)++ans;
55         t = X[i] +  1;
56     }
57      for(i = len- 2;i >=  0;--i)ans += S[i] - F[i][ 1];
58      return ans;
59 }
60  
61 inline  void work(){
62      int a, b;
63     getd(a), getd(b);
64      // while(~scanf("%d%d", &a, &b))
65      printf( " %d\n ", calc(b) - calc(a- 1));
66 }
67  
68  int main(){
69  
70 #ifdef DEBUG
71      // freopen("test.txt", "r", stdin);
72  #elif !defined ONLINE_JUDGE
73     SetFile(bzoj_1026);
74  #endif
75     init();
76     work();
77  
78 #ifdef DEBUG
79     printf( " \n%.2lf sec \n ", ( double)clock() / CLOCKS_PER_SEC);
80  #endif
81      return  0;
82 }
数位dp

 

转载于:https://www.cnblogs.com/Asm-Definer/p/4374066.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值