【解题思路】
1、将数字拆分保存在数组中,而后转换每一位。
2、将数字变化规则保存在x、y两个一维数组中,x[i]到y[i]是一种转换规则。
3、从n的初始值开始搜索,对n做数字拆分,将拆分后的各位数字保存在一个数组中。针对数组中的每位数字,看能否通过转换规则将该数字转换为另一个数字。如果可以,那么做一次转换,将该数组通过数字组合变为一个整数,通过vis数组判断该整数是否出现过。如果出现过,那么略过。如果没出现过,将该整数在vis数组中设为“出现过”,产生的数字个数加1,而后从该整数开始再次进行搜索。
输入样例分析
234
2
2 5
3 6
【参考代码】
广搜
#include<bits/stdc++.h>
using namespace std;
#define K 20
int n, k, ct, x[K], y[K], arr[5], ai;
bool vis[10001];
void toArr(int num)//将整数num进行数字拆分,结果保存在数字数组arr中。(包括num为0的情况)
{ai = 0;int a = num;do{arr[++ai] = a % 10;a /= 10;}while(a > 0);
}
int toNum()//将数字数组arr保存的数字转为整型数字
{int num = 0;for(int i = ai; i >= 1; --i)num = num * 10 + arr[i];return num;
}
void bfs()
{queue<int> que;vis[n] = true;ct = 1;que.push(n);while(que.empty() == false){int u = que.front();que.pop();toArr(u);//将u转为数字数组arr for(int i = 1; i <= ai; ++i)//遍历arr中的每一位 {for(int j = 1; j <= k; ++j)//遍历每条规则 {if(arr[i] == x[j]){arr[i] = y[j];int newNum = toNum();if(vis[newNum] == false){vis[newNum] = true;ct++;que.push(newNum);}arr[i] = x[j];//还原 }}}}
}
int main()
{cin >> n >> k;for(int i = 1; i <= k; ++i)cin >> x[i] >> y[i];bfs();cout << ct;return 0;
}
深搜
#include <bits/stdc++.h>
using namespace std;
int n, k, x[20], y[20], arr[5], ai, ct;
bool vis[10000];
void toArr(int num)//将整数num进行数字拆分,结果保存在数字数组arr中。(包括num为0的情况)
{ai = 0;int a = num;do{arr[++ai] = a % 10;a /= 10;}while(a > 0);
}
int toNum()//将数字数组arr保存的数字转为整型数字
{int num = 0;for(int i = ai; i >= 1; --i)num = num * 10 + arr[i];return num;
}
void dfs(int num)
{int temp, newNum;for(int i = 1; i <= ai; ++i){for(int j = 1; j <= k; ++j)//如果存在替换arr[i]的规则 {if(arr[i] == x[j]){arr[i] = y[j];newNum = toNum();//合成得到新的整数 if(vis[newNum] == false)//如果新的整数nweNum没出现过 {vis[newNum] = true;//将newNum标记为出现过 ct++;//数字出现的个数加1 dfs(newNum);}arr[i] = x[j];//还原 }}}
}
int main()
{cin >> n >> k;for(int i = 1; i <= k; ++i)cin >> x[i] >> y[i];toArr(n);vis[n] = true;ct = 1;dfs(n);cout << ct;return 0;
}