MYQ10 Mirror Number (數位DP)
阿新 • • 發佈:2018-12-10
Description
A number is called a Mirror number if on lateral inversion, it gives the same number i.e it looks the same in a mirror. For example 101 is a mirror number while 100 is not.
Given two numbers a and b, find the number of mirror numbers in between them (inclusive of a and b).
Input
First line contains T, number of testcases <= 10^5. Each testcase is described in a single line containing two numbers a and b. 0 <= a<=b <= 10^44
Output
For each test case print the number of mirror numbers between a and b in a single line.
Example
Input: 3 0 10 10 20 1 4 Output: 3 1 1
演算法分析:
數位Dp求迴文串,(點選這裡),這題要求是1或0或8,且輸入為字串形式(10e44),轉化一下就行,難點在於m-1,我們需要單獨判斷m-1
#include<bits/stdc++.h> using namespace std; typedef long long ll; char a[50]; int b[50]; ll dp[50][50][50]; ll dfs(int pos,int s,bool sta,int lead,int limit) //s表示迴文串的起點,pos表示正在搜尋的位,sta表示目前構成的串是否為迴文串 { if(pos==-1){ return sta; } if(!limit&&!lead&&dp[pos][s][sta]!=-1) return dp[pos][s][sta]; int up=limit?(a[pos]-'0'):9; ll tmp=0; for(int i=0;i<=up;i++) { if(i==0||i==8||i==1) { b[pos]=i; if(lead==1&&i==0) //前導0 { tmp+=dfs(pos-1,s-1,sta,lead,limit&&i==up); } else { if(sta&&pos<(s+1)/2)//草稿紙看看 //列舉後半段 tmp+=dfs(pos-1,s,b[s-pos]==i,lead && i==0,limit&&i==up); else //填充前半段 tmp+=dfs(pos-1,s,sta,lead && i==0,limit&&i==up); } } } if(!limit&&!lead) dp[pos][s][sta]=tmp; return tmp; } ll solve(string x) { int pos=0; int len=x.length(); for(int i=0;i<len;i++) a[i]=x[len-1-i]; return dfs(len-1,len-1,1,true,true);//注意sta一開始要初始化為1,找了好久,因為無也是個迴文字串 } int main() { memset(dp,-1,sizeof(dp)); int T; cin>>T; for(int i=1;i<=T;i++) { string n,m; cin>>n>>m; ll ans=solve(m)-solve(n); int len=n.length(); int flag=1; for(int i=0;i<len;i++) { if((n[i]!='8'&&n[i]!='1'&&n[i]!='0')||n[i]!=n[len-i-1]) { flag=0; break; } } if(flag==1) ans++; printf("%lld\n",ans); } return 0; }