2018蓝桥杯模拟赛(一)H【floyd求最短路径】

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

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

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

输入格式

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

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

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

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

输出格式

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

样例输入

abcd
dddd
3
a b
b c
c d
样例输出

6

思路:本来是利用map记录字符转换,然后通过循环查找知道两个字符一样。但是呢,超时。。。原来这个求任意两个字符之间的最短路径。用弗洛伊德算法。
原来的代码:

#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
using namespace std;
char a[1005];
char b[1005];
int k;
int cnt = 0;
map<char,char> mp;

int main()
{
    char ch;
    int i = 0;
    char p,q;
    while(scanf("%c",&ch)&&ch != '\n')
    {
        a[i++] = ch;
    }
    //a[i] = '\0';
    i = 0;
    while(scanf("%c",&ch)&&ch != '\n')
    {
        b[i++] = ch;
    }
    cin>>k;
    for(int i = 0;i<k;i++)
    {
        cin>>p>>q;
        mp[p] = q;
    }
    for(int i =0;i<strlen(a);i++)
    {
        while(a[i]!=b[i])
        {
            a[i] = mp[a[i]];
            cnt++;
        }
    }

    cout<<cnt<<endl;

    return 0;
}

floyd()算法的核心只有五句

void Flody()
{
    for(int k = 0;k<=n;k++)
    for(int i = 0;i<n;i++)
    for(int j = 0;j<n;j++)
    {
    if(m[i][j] > m[i][k]+m[k][j])
        m[i][j] = m[i][k]+m[k][j];
    }

}
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char a[1005];
char b[1005];
int dis[28][28];
const int inf = 100000000; 
int k;
int cnt = 0;
void floyd();
int main()
{
    char p,q;
    scanf("%s",a);

    scanf("%s",b);//总是忘记用%s读入
    int len = strlen(a);
    cin>>k;
    for(int i = 0;i<26;i++)
    {
        for(int j = 0;j<26;j++)
        {
            dis[i][j] = inf;
        }
        dis[i][i] = 0;
    }
    while(k--)
    {
        //getchar(); 
    //  scanf("%c",&p);
    //  getchar();//读空格 
    //  scanf("%c",&q);
    //  getchar();//读回车 
    //  dis[p-'0'][q-'0'] = 1;
        char s[3],e[3];
        scanf("%s%s",s,e); //%s是遇到空字符停止,而gets取得字符串时,是在遇到EOF(串尾)时停止 
        if(s[0]!=e[0])
            dis[s[0]-'a'][e[0]-'a']=1;
    }
    floyd();
    for(int i = 0;i<len;i++)
    {
        if(dis[a[i]-'a'][b[i]-'a']>=inf)
        {
            cout<<-1<<endl;
            return 0;
        }
        else cnt += dis[a[i]-'a'][b[i]-'a'];
    }
    cout<<cnt<<endl;
    return 0;
}
void floyd()
{
    for(int m = 0;m<26;m++)
    {
        for(int i = 0;i<26;i++)
        {
            for(int j = 0;j<26;j++)
            {
                if(dis[i][j]>dis[i][m]+dis[m][j])
                    dis[i][j]=dis[i][m]+dis[m][j];
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_38293125/article/details/79711673