最开始错误的思路是对整条字串进行dfs,看一位dfs进入下一位,这是没有充分理解题意的后果
核心解题思路:不要被这些规则变来变去搞混了,我们需要将原问题进行切割成小的子问题去分析。例如此处我们将每一位数都当做一个独立单位,首先求出在这个位置上有多少种可以存在的数的种类(0~9)。而这些独立单位(位置)互不相同,彼此独立,因此求出总的可变换的数的总数则是每个位置上的数的种类的累乘。对每一位上的数操作时,把变换的规则当做是点与点的连接(一共有10个点位0~9)。因此想要访问所有能走的点(有多少点则有个种类的数),因此这一遍历全部图的思想符合dfs的性质
注意:在数的第一个位置上,我们假设0的存在是合法的,比如0123实际上是123,但它也带来了一个新的数字,因此种类也会增加
实现代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lll __uint128_t 4 5 char s[100]; //用于储存整数 6 int memory[100]={0}; //用于数有多少种变换种类 实质是一个优化,记忆化储存 7 lll ans; //用于储存数的种类 8 int num=0; //记录每个位置上有多少种类数 9 int flag[100]={0}; //用于dfs中标志 同样直接拿字符'0'~'9'当做下标 10 int k=0; //规则数 11 char a[20],b[20]; //储存变换规则 12 13 void out(lll x){//int128输出要自己写 14 if(x>9)out(x/10); 15 putchar(x%10+48); 16 } 17 void dfs(char index){ 18 flag[index]=1; //走过标记为1 19 num++; //访问到一个点就加一 20 21 for(int i=1;i<=k;i++){ 22 if(index==a[i]){ 23 if(flag[b[i]]) continue; //访问过 24 dfs(b[i]); 25 //这里不能加上回溯,因为不会重复访问同一个点 26 } 27 } 28 return ; 29 30 } 31 int main(){ 32 ios::sync_with_stdio(false); //加快数据的输入和输出 33 cin.tie(0); 34 cout.tie(0); 35 ans=1; //初始化为1 36 37 cin>>s>>k; 38 for(int i=1;i<=k;i++){ 39 cin>>a[i]>>b[i]; 40 } 41 42 for(int i=0;s[i]!='