封印之门(最短路径)

 

 

我的代码:深度优先搜索,且每次改变时都要搜索一遍,所以导致超时

import java.util.Scanner;

public class 封印之门 {
	public static int k,len,sum,flag;
	public static boolean c[][] = new boolean[26][26];
	public static boolean vis[] = new boolean[26];
	public static String a,b;

	public static void main(String[] args) {
		Scanner sca = new Scanner(System.in);
		a = sca.nextLine();
		b = sca.nextLine();
		len = b.length();
		k = sca.nextInt();
		sca.nextLine();
		for(int i = 0;i < k;i ++) {
			String t1 = new String();
			
			t1 = sca.nextLine();
			//System.out.println(t1.charAt(0));
			//System.out.println(t1.charAt(2));
            c[t1.charAt(0) - 'a'][t1.charAt(2) - 'a'] = c[t1.charAt(2) - 'a'][t1.charAt(0) - 'a'] = true;			
		}
		
		for(int i = 0;i < len;i ++) {
			if(a.charAt(i) != b.charAt(i)) {
				int t1 = a.charAt(i) - 'a';
				int t2 = b.charAt(i) - 'a';
				sum += find(t1,t2);
				//System.out.println(find(t1,t2));
			}
			if(flag == 1) {
				System.out.println(-1);
				return;
			}
		}
		System.out.println(sum);

	}

	private static int find(int t1, int t2) {
		int num = 0;
		num = dfs(t1,t2,0);
		if(num == 1000000) {
			flag = 1;
		}
		return num;
	}

	private static int dfs(int t1, int t2, int num) {
		int min = 1000000;
		if(c[t1][t2]) {
			num ++;
			//System.out.println(num);
			return num;
		}
		int t = 100000000;
		for(int i = 0; i < 26; i ++) {
			
			if(c[t1][i] && !vis[i]) {
			  vis[i] = true;
			  t = dfs(i,t2,num + 1);
			  vis[i] = false;
			}
			if(t < min) {
				min = t;
			}
		}
		return min;
	}

}

 分析:题目本质就是要寻找最短路径,其中要计算步数,所以不用bfs,用最短路径算法:迪杰斯特拉算法或者弗洛伊德算法。

/*
 * 封印之门,转化为图的问题
 */
import java.util.Scanner;
public class fengyin_door {
	
	public static int min(int a,int b) {
		if(a>b) a=b;
		return a;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//利用图和矩阵的思想解决
		int N=1010;
		 int inf=999999;
		 int[][] g=new int[30][30];//26阶矩阵
		 char[] fengyin=new char[N];
		 char[] jiefeng=new char[N];
		 int x;
		 int len;
		for(int i=0;i<26;++i)
			for(int j=0;j<26;++j) {
				if(i==j) {
					g[i][j]=0;//自己到自己则置为0
				}
				else {
					g[i][j]=inf;//初始无此路径,则无穷
				}
			}
		Scanner cin=new Scanner(System.in);
		fengyin=cin.next().toCharArray();
		len=fengyin.length;
		jiefeng=cin.next().toCharArray();
		char a,b;
		x=cin.nextInt();
		for(int i=0;i<x;i++) {
			a=cin.next().charAt(0);
			b=cin.next().charAt(0);
			if(a!=b) g[a-'a'][b-'a']=1;//a-b是一条路径则置1
		}
		for(int k=0;k<26;++k)
			for(int i=0;i<26;++i)
				for(int j=0;j<26;++j) {
					g[i][j]=min(g[i][j],g[i][k]+g[k][j]);//和inf(无穷)比更新更小的;
				}
		int sum=0;
		for(int i=0;i<len;++i) {
			if(g[fengyin[i]-'a'][jiefeng[i]-'a']>=inf) {
				sum=-1;
				break;
			}
			else {
				sum+=g[fengyin[i]-'a'][jiefeng[i]-'a'];
			}
		}
		System.out.println(sum);
		
	}
 
}

参考资料:

 

https://blog.csdn.net/sinat_37341950/article/details/79242639  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值