封印之门(最短路)

问题

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

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

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

输入格式

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

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

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

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

输出格式

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

样例输入

abcd
dddd
3
a b
b c
c d

样例输出

6

思路:

这是最短路问题,
可以参考:最短路详解

代码实现

public class Main16 {
    //表示封印之门上的字母
    static char[] c1=new char[1005];  
    //表示解开封印之门的文字
    static char[] c2=new char[1005];
    //数组
    static int[][] e=new int[30][30];
    public static void init() {//初始化   
        for(int i = 1; i <= 26; i++) {  
            for(int j = 1; j <= 26; j++) {  
                if(i == j) e[i][j] = 0;//两个相同的字母互相转化不需要步数   
                else e[i][j]=1000000;       //初始将两个字母之间的转化赋值为1000000
            }  
        }  
    }  
    public static void Floyd() {//跑最短路   
        for(int k = 1; k <= 26; k++) {  
            for(int i = 1; i <= 26; i++) {  
                for(int j = 1; j <= 26; j++) {  
                    if(i == j) continue;  
                    if(e[i][j] > e[i][k] + e[k][j])  
                        e[i][j] = e[i][k] + e[k][j];  
                }  
            }  
        }     
    }
    public static void main(String[] args) {
        int n;  
        char C1, C2;
        Scanner sc=new Scanner(System.in);
        String str1=sc.next();
        c1=str1.toCharArray();
        String str2=sc.next();
        c2=str2.toCharArray();
        n=sc.nextInt();
        init();  
        long sum = 0;  
        while(n!=0) {  
            C1=sc.next().charAt(0);
            C2=sc.next().charAt(0);
            //有可能输入两个字母是相同的(字母相同表示自己到自己的距离为0,不是1)
            if(C1 != C2)  
            e[C1-'a'+1][C2-'a'+1] = 1;//建图
            n--;
        }  
        Floyd();   
        int m = c1.length;  
        //从0开始,计算c[i]
        for(int i = 0; i < m; i++) {  
            //如果没有对应路径,则两点之间的距离为初始化的距离
            sum += e[c1[i]-'a'+1][c2[i]-'a'+1];//求出步数   
        }  
        if(sum<1000000){
            System.out.println(sum);
        }else{
            //没有找到时,由于初始化为1000000,所有会大于1000000
            System.out.println(-1);
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值