题目链接:https://nanti.jisuanke.com/t/A1594
蒜头君被暗黑军团包围在一座岛上,所有通往近卫军团的路都有暗黑军团把手。幸运的是,小岛上有一扇上古之神打造的封印之门,可以通往近卫军团,传闻至今没有人能解除封印。
封印之门上有一串文字,只包含小写字母,有 k种操作规则,每个规则可以把一个字符变换成另外一个字符。经过任意多次操作以后,最后如果能把封印之门上的文字变换成解开封印之门的文字,封印之门将会开启。
蒜头君战斗力超强,但是不擅计算,请你帮忙蒜头君计算至少需要操作多少次才能解开封印之门。
输入格式
输入第一行一个字符串,长度不大于 1000,只包含小写字母,表示封印之门上的文字。
输入第二行一个字符串,只包含小写字母,保证长度和第一个字符串相等,表示能解开封印之门的文字。
输入第三行一个整数 k(0≤k≤676)。
接下来 kk 行,每行输出两个空格隔开的字符 aa, bb,表示一次操作能把字符 aa 变换成字符 bb。
输出格式
如果蒜头君能开启封印之门,输出最少的操作次数。否则输出一行 -1。
样例输入复制
abcd dddd 3 a b b c c d
样例输出复制
6
题目来源
解题思路:分下知,这是求一个字符转化为另一个字符的最少步数问题,即归纳为最短路问题(Flod算法)。
注意:这个题有坑,代码里面会说明,当时没考虑到,只过了两个样例。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <stack> #include <queue> #include <vector> #include <string> #define cla(a, sum) memset(a, sum, sizeof(a)) #define rap(i, m, n) for(i=m; i<=n; i++) #define rep(i, m, n) for(i=m; i>=n; i--) using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll, ll> P; const int Inf = 0x3f3f3f3f; const double eps = 1e-8; const int maxn = 1e3+5; string s,s1; int k,n; int f[30][30]; void init(){ int i,j; rap(i,0,29){ rap(j,0,29){ f[i][j]=1e5; } f[i][i]=0;//相同之间转化步数为0 } } int main() { cin>>s>>s1; int i,j,u,v; n=s.size() ; init();//初始化 cin>>k;getchar(); char l,r; rap(i,1,k){ scanf("%c %c",&l,&r); // cout<<l<<r<<endl; getchar(); u=l-'a'+1; v=r-'a'+1; if(u!=v)//注意u和v可能相等,此时就不能赋值1了 f[u][v]=1; } for(u=1;u<=26;u++){ for(i=1;i<=26;i++){ for(j=1;j<=26;j++){ f[i][j]=min(f[i][j],f[i][u]+f[u][j]); } } } int sum=0; for(i=0;i<n;i++){ u=s[i]-'a'+1; v=s1[i]-'a'+1; if(f[u][v]>=1e5){ printf("-1"); return 0; } sum+=f[u][v]; } cout<<sum; return 0; }