题目链接:http://acm.uestc.edu.cn/problem.php?pid=1307
题目大意:
不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。windy想知道,在A和B之间,包括A和B,总共有多少个windy数?
思路:
具体解释代码中有。看的这个人的代码:http://blog.csdn.net/acm_cxlove/article/details/7819907# 然后自己又分析了一下,终于明白了。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cctype> 6 #include <stack> 7 #include <queue> 8 #include <cmath> 9 #include <algorithm> 10 #define lson l, m, rt<<1 11 #define rson m+1, r, rt<<1|1 12 using namespace std; 13 typedef long long int LL; 14 const int MAXN = 0x3f3f3f3f; 15 const int MIN = -0x3f3f3f3f; 16 const double eps = 1e-9; 17 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1}, 18 {1,1},{1,-1},{-1,-1}}; 19 int dp[15][10], a[15]; 20 // 这个函数求的是区间(0,n)内的个数 21 LL solve(int n){ 22 int len = 0; LL ans = 0; 23 while (n){ 24 a[++len] = n % 10; n /= 10; 25 }int i, j; a[len+1] = 0; 26 // 长度为1~len-1 27 for (i = 1; i <= len-1; ++i) 28 for (j = 1; j <= 9; ++j) // 注意j从1开始,因为最高位不能是0! 29 ans += dp[i][j]; // debug了好久!!! 30 // 长度为len,但是最高位是a[len] - 1 31 for (i = 1; i <= a[len] - 1; ++i) 32 ans += dp[len][i]; 33 // 长度为len,但是最高位是a[len] 34 for (i = len - 1; i >= 1; --i){ 35 for (j = 0; j < a[i]; ++j) 36 if (abs(a[i+1] - j) >= 2) 37 ans += dp[i][j]; 38 if (abs(a[i] - a[i+1]) < 2) 39 break; 40 } 41 return ans; 42 } 43 int main(void){ 44 #ifndef ONLINE_JUDGE 45 freopen("uestcoj1307.in", "r", stdin); 46 #endif 47 memset(dp, 0, sizeof(dp)); 48 int i, j, k; 49 for (i = 0; i <= 9; ++i) 50 dp[1][i] = 1; 51 for (i = 2; i <= 10; ++i) 52 for (j = 0; j <= 9; ++j) 53 for (k = 0; k <= 9; ++k) 54 if (fabs(j - k) >= 2) 55 dp[i][j] += dp[i-1][k]; 56 int a, b; 57 while (~scanf("%d%d", &a, &b)){ 58 cout << solve(b+1) - solve(a) << endl; 59 } 60 return 0; 61 }
比较坑的是电子科大的OJ上不支持#ifndef ONLINE_JUDGE 所以RE了好久……