计蒜客-封印之门(简单Floyd应用)

蒜头君被暗黑军团包围在一座岛上,所有通往近卫军团的路都有暗黑军团把手。幸运的是,小岛上有一扇上古之神打造的封印之门,可以通往近卫军团,传闻至今没有人能解除封印。

封印之门上有一串文字,只包含小写字母,有 kkk 种操作规则,每个规则可以把一个字符变换成另外一个字符。经过任意多次操作以后,最后如果能把封印之门上的文字变换成解开封印之门的文字,封印之门将会开启。

蒜头君战斗力超强,但是不擅计算,请你帮忙蒜头君计算至少需要操作多少次才能解开封印之门。

输入格式

输入第一行一个字符串,长度不大于 1000,只包含小写字母,表示封印之门上的文字。

输入第二行一个字符串,只包含小写字母,保证长度和第一个字符串相等,表示能解开封印之门的文字。

输入第三行一个整数 k(0≤k≤676)k(0 \le k \le 676)k(0≤k≤676)。

接下来 kkk 行,每行输出两个空格隔开的字符 aaa, bbb,表示一次操作能把字符 aaa 变换成字符 bbb。

输出格式

如果蒜头君能开启封印之门,输出最少的操作次数。否则输出一行 −1-1−1。

样例输入

abcd
dddd
3
a b
b c
c d

样例输出

6

时间限制:1000ms

扫描二维码关注公众号,回复: 2843564 查看本文章

思路:简单的最短路问题,要求最小操作次数,第一反应是贪心,但是可能出现有环的情况,贪也不好贪。因为每一个字符若不相等都会进行操作,所以可以看做单独的个体,也就是一个点,每次操作可以将操作前后的2个字符当作点来处理,边权便是操作的次数,因为该题的图很小,只有26个字母,也就是26^2的图,也不存在负环情况,所以用暴力Floyd(最简单)直接跑一遍即可。

代码如下:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string>
#include<string.h>
#define per(i,a,b) for(int i=a;i<=b;i++)
#define inf 0x3f3f3f3f
using namespace std;
int main()
{
	int p[30][30],i,j,t;	
	string s,s1;
	cin>>s>>s1;
	per(i,0,27)
	{
		per(j,0,27)
		{
			if(i==j) p[i][j]=0;
			else p[i][j]=inf;
		}
	}
	cin>>t;
	per(i,1,t)
	{
	    char a,b;
		cin>>a>>b;
		if(a!=b)
		p[a-'a'][b-'a']=1;
	} 
	per(k,0,26)
	{
		per(i,0,26)
		{
			per(j,0,26)
			{
				p[i][j]=min(p[i][j],p[i][k]+p[k][j]);
			}
		}
	}
	int z=0;
	for(i=0;i<s.size();i++)
	{
		if(p[s[i]-'a'][s1[i]-'a']==inf)
		{
			printf("-1\n");return 0;
		}
		else
		z+=p[s[i]-'a'][s1[i]-'a'];
	}
	printf("%d\n",z);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/PleasantlY1/article/details/81487849
今日推荐