[代码]SPOJ 10649 Mirror Number
Abstract
数位dp, 统计
Body
注意题目的意思是只要考虑 '0' , '1' 和 '8' 三个数字。
很普通的数位dp题……我居然还WA了2次T_T
#include <iostream> #include <string> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; int T; char a[50], b[50]; LL f[50], g[50]; void init() { int i, j; f[0] = 1; for (i = 1; i <= 45; ++i) if (i&1) f[i] = f[i-1]*3; else f[i] = f[i-1]; g[1] = 3; g[2] = 2; for (i = 3; i <= 45; ++i) if (i&1) g[i] = g[i-1]*3; else g[i] = g[i-2]*3; } inline bool mirror(char c) {return c=='0'||c=='1'||c=='8';} bool test(int len, char *s, char c) { char t[50]={0}; for (int i = 0; i < len>>1; ++i) { if (!mirror(s[i])) return 0; t[i] = t[len-1-i] = s[i]; } if (len&1) t[len>>1] = c; return strcmp(s, t)>=0; } bool judge(int len, char *s) { for (int i = 0; i < len+1>>1; ++i) { if (!mirror(s[i])) return 0; if (s[i] != s[len-1-i]) return 0; } return 1; } LL calc(int len, char *s) { int i, j, k; LL res = 0, tmp; for (i = 1; i < len; ++i) res += g[i]; for (i = 0; i < len>>1; ++i) { tmp = f[len-(i+1<<1)]; if (i && s[i]>'0') res += tmp; if (s[i]>'1') res += tmp; if (s[i]>'8') res += tmp; if (!mirror(s[i])) break; } if (len&1) { res += test(len, s, '0'); res += test(len, s, '1'); res += test(len, s, '8'); } else res += test(len, s, 0); return res; } int main() { init(); cin>>T; LL ans; int len; while (T--) { /* scanf("%s", a); printf("%lld\n", calc(strlen(a), a)); */ scanf("%s%s", a, b); ans = calc(strlen(b), b)-calc(strlen(a), a); ans += judge(strlen(a), a); printf("%lld\n", ans); } return 0; }