题目大意:
求区间内的回文数个数
题目思路:
数位dp,先枚举前一半数字,然后填上相应的后一半数字。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<stack> #define MAXSIZE 1000005 #define LL long long using namespace std; LL dp[55][55][2]; int temp[MAXSIZE],bit[MAXSIZE]; LL dfs(int pos,int st,int pre,int limit) { if(pos < 1) return 1; if(!limit && dp[pos][st][pre]!=-1) return dp[pos][st][pre]; int len = limit?bit[pos]:9; LL ans = 0; for(int i=0;i<=len;i++) { temp[pos] = i; if(pre==0 && i==0) { ans += dfs(pos-1,st-1,0,i==len&&limit); } else if(pos > st/2) //枚举前一半 { ans += dfs(pos-1,st,1,i==len&&limit); } else if(temp[pos] == temp[st-pos+1]) //填上后一半 { ans += dfs(pos-1,st,1,i==len&&limit); } } if(!limit) dp[pos][st][pre] = ans; return ans; } LL Solve(LL n) { int pos = 0; memset(dp,-1,sizeof(dp)); while(n) { bit[++pos] = n%10; n /= 10; } LL ans = dfs(pos,pos,0,1); return ans; } int main() { int T,cns=1; LL n,m; scanf("%d",&T); while(T--) { scanf("%lld%lld",&n,&m); if(n > m) swap(n,m); LL ans = Solve(m) - Solve(n-1); printf("Case %d: %lld ",cns++,ans); } return 0; }