计蒜客 封印之门(思维+Floyd)

33 篇文章 0 订阅
31 篇文章 0 订阅

传送门


思路:

    个人感觉是很巧妙的一题啊,总觉得很熟悉但就是差点意思...

   首先分析一下bfs是没戏了,每个字母最多26中变换方法(可以自己变成自己),最长1000,26^1000 ,hhh 

    感觉这题加深了对Floyd的理解吧,由于是小写字母也就是最多有26个城市,我们可以先不去考虑整个字符串,只看把某个字符变为要求的字符需要几步,然后在遍历整个串求出总共需要的步数即可.我们把每一次操作变换看成是一条权值为1的有向边,就发现这是个多元最短路问题了(其实给定你k次变换操作,就相当于是给你了k条右向边啊。)

#include <bits/stdc++.h>

#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 30;
string st,dt;
ll mp[30][30],k;
int main()
{
	while(cin >> st >> dt >> k)
	{
		for(int i = 0;i <= 26;++i)
		{
			for(int j = 0;j <= 26;++j)
			{
				if(i == j) 
					mp[i][i] = 0;
				else
					mp[i][j] = inf;
			}
		}
		for(int i = 1;i <= k;++i)
		{
			char s1[5],s2[5];
			scanf("%s %s",s1,s2);
			if(s1[0] == s2[0]) continue;
			mp[s1[0] - 'a'][s2[0] - 'a'] = 1;
		}
		for(int kk = 0;kk < 26;++kk)
			for(int i = 0;i < 26;++i)
				for(int j = 0;j < 26;++j)
					mp[i][j] = min(mp[i][j],mp[i][kk] + mp[kk][j]);
		bool flag = 1;
		ll ans = 0;
		for(int i = 0;i < st.size();++i)
		{
			ll dis = mp[st[i] - 'a'][dt[i] - 'a'];
			if(dis >= inf)
			{
				flag = 0;
				break;
			}
			ans += dis;
		}
		if(flag)
			printf("%lld\n",ans);
		else
			puts("-1");
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Marcus-Bao

万水千山总是情,只给五角行不行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值