Y

来源:互联网 发布:淘宝客服骂人不带脏字 编辑:程序博客网 时间:2024/04/25 14:47

Y - odd-even number

 

题意:

一个数,每连续的奇数位以及连续的偶数位为一段,要求每一个奇数段(连续奇数组成的段)要有偶数个奇数,每一个偶数段(连续偶数组成的段)要有奇数个偶数,求区间[L,R]有多少个满足条件的。

思路:

dp[i][j] i代表位置,j代表状态,此题目中总共有五个状态,0代表前导零,1代表奇数为奇数个,2代表奇数为偶数,3代表偶数为奇数,4代表偶数为偶数个,总共五个状态,一一列举出来,注意limit位置不同,结果奴不一样

代码:

#include <iostream>#include <cmath>#include <cstdio>#include <cstring>#include <algorithm>typedef long long LL;using namespace std;typedef long long LL;int a[25];LL dp[25][5];LL dfs(int pos, int limit, int sta){if (pos < 1){if (sta == 2 || sta == 3)return 1;elsereturn 0;}if (!limit&&dp[pos][sta]!=-1) return dp[pos][sta];int up = limit?a[pos]:9;LL ans = 0;for (int i = 0; i <= up; i++){if (!sta){if (!i){ans += dfs(pos - 1, 0, 0);}else if (i & 1){ans += dfs(pos - 1, limit&&i == up, 1);}else{ans += dfs(pos - 1, limit&&i == up, 3);}}else{if (sta == 1){if (i & 1){ans += dfs(pos - 1, limit&&i == up, 2);}}else if (sta == 2){if (i & 1){ans += dfs(pos - 1, limit&&i == up, 1);}else{ans += dfs(pos - 1, limit&&i == up, 3);}}else if (sta == 3){if (i & 1){ans += dfs(pos - 1, limit&&i == up, 1);}else{ans += dfs(pos - 1, limit&&i == up, 4);}}else{if (!(i & 1)){ans += dfs(pos - 1, limit&&i == up, 3);}}}}dp[pos][sta] = ans;return ans;}LL cal(LL x){memset(dp, -1, sizeof(dp));int len = 0;while (x){a[++len] = x % 10;x /= 10;}return dfs(len, 1, 0);}int main(){int t;scanf("%d", &t);for (int cas = 1; cas <= t; cas++){LL l, r;scanf("%lld%lld", &l, &r);printf("Case #%d: %lld\n", cas, cal(r) - cal(l - 1));}}


原创粉丝点击