专栏文章

题解:SP10649 MYQ10 - Mirror Number

SP10649题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@miofy9k3
此快照首次捕获于
2025/12/02 18:34
3 个月前
此快照最后确认于
2025/12/02 18:34
3 个月前
查看原文
数位 dp 板题,真没什么好说的。
dp(x,y)\text{dp(x,y)} 表示枚举到第 x\text{x} 位,最高位(不是 0 的第一位)为 y\text{y} 时的总方案数。
每次向下一位递归的时候排除所有不合法方案,这样就能保证最后筛选出来的都是合法情况。
向上递归的时候累加下一位所有合法方案。
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=50;
int dp[N][N],a[N],b[N],ans,x;
string l,r;
int dfs(int pos,int st,bool lim){
	if(!pos){
		return 1;
	}
	if(!lim&&dp[pos][st]!=-1) return dp[pos][st];
	int up=lim?a[pos]:9;
	int ans=0;
	for(int i=0;i<=up;++i){
		if((i!=0&&i!=8&&i!=1)||((pos<=st/2)&&i!=b[st-pos+1])) continue;
		b[pos]=i;
		ans+=dfs(pos-1,st-(st==pos&&!i),lim&(i==up));
	}
	if(!lim) dp[pos][st]=ans;
	return ans;
}
int sol(string s){
	reverse(s.begin(),s.end());
	int x=s.size();
	for(int i=0;i<x;++i) a[i+1]=s[i]-'0';
	return dfs(x,x,1);
}
bool check(string s){
	int len=s.size();
	for(int i=0;i<len;i++){
		if(s[i]!='0'&&s[i]!='1'&&s[i]!='8'){
			return 0;
		} 
		if(s[i]!=s[len-i-1]){
			return 0;
		} 
	}
	return 1;
}
signed main(){
    memset(dp,-1,sizeof(dp));
    int T;
    cin>>T;
    while(T--){
		cin>>l>>r;
		cout<<sol(r)-sol(l)+check(l)<<endl;
	}
    return 0;
}

评论

1 条评论,欢迎与作者交流。

正在加载评论...