SPOJ MYQ10 10649. Mirror Number (数位dp)

来源:互联网 发布:淘宝产品关联怎么做 编辑:程序博客网 时间:2024/05/23 12:57

SPOJ MYQ10 10649. Mirror Number (数位dp)

ACM

题目地址:SPOJ MYQ10 Mirror Number

题意: 
求[a,b]中镜像回文的个数。 
0 <= a<=b <= 10^44

分析: 
看到题目和数据范围就知道是数位dp了。 
很明显镜像回文只有0,1,8,跟回文的一题一样,在dfs的时候得开个辅助数组记录前面已经选择的数字。 
注意还得去掉前导0。

代码

/**  Author:      illuz <iilluzen[at]gmail.com>*  Blog:        http://blog.csdn.net/hcbbt*  File:        10649_MYQ10.cpp*  Create Date: 2014-08-02 14:20:31*  Descripton:  MYQ10, digit dp*/#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define repf(i,a,b) for(int i=(a);i<=(b);i++)typedef long long ll;const int N = 50;ll dp[N][N][2];// dp[start][current][ismirror]char bit[N], num[N];int t, rec[N], len;// the start pos, current pos, ismirror flag, is limit flag// this function will use rec[] to record the prevent chosen numbersll dfs (int start, int cur, bool ismir, bool limit) {if (cur < 0)return ismir;if (!limit && dp[start][cur][ismir] != -1)return dp[start][cur][ismir];int mmax = limit ? bit[cur] - '0' : 9;ll ret = 0;repf (i, 0, mmax) {if (i == 0 || i == 1 || i == 8) {rec[cur] = i;if (start == cur && i == 0) {// if have lead zeroret += dfs(start - 1, cur - 1, ismir, (limit && (i == mmax)));} else if (ismir && cur < (start + 1) / 2) {// if ismirror and can judgeret += dfs(start, cur - 1, (i == rec[start - cur]), (limit && (i == mmax)));} else {ret += dfs(start, cur - 1, ismir, (limit && (i == mmax)));}}}return limit ? ret : dp[start][cur][ismir] = ret;}// check if first number is mirrorbool check() {repf (i, 0, len >> 1) {if (bit[i] != '0' && bit[i] != '1' && bit[i] != '8')return false;if  (bit[i] != bit[len - 1 - i])return false;}return true;}ll solve() {ll ans1, ans2;// first numberscanf("%s", num);len = strlen(num);repf (i, 0, len - 1)bit[i] = num[len - 1 - i];bit[len] = 0;ans1 = dfs(len - 1, len - 1, 1, 1) - check();//cout << ans1 << endl;// second numberscanf("%s", num);len = strlen(num);repf (i, 0, len - 1)bit[i] = num[len - 1 - i];bit[len] = 0;ans2 = dfs(len - 1, len - 1, 1, 1);//cout << ans2 << endl;cout << ans2 - ans1 << endl;}int main() {memset(dp, -1, sizeof(dp));scanf("%d", &t);while (t--) {solve();}return 0;}


2 0
原创粉丝点击