P1032 字串变换
题目描述
已知有两个字串 A,BA,B 及一组字串变换的规则(至多 66 个规则):
A1 ->B1
A2 -> B2
规则的含义为:在 A 中的子串 A1 可以变换为B1,A2 可以变换为 B2 …。
例如:A=abcd,B=xyz,
变换规则为:
abc→xu,ud→y,y→yz
则此时,A 可以经过一系列的变换变为 B,其变换的过程为:
abcd→xud→xy→xyz。
共进行了 3 次变换,使得 A 变换为 B。
输入格式
输入格式如下:
A B
A1 B1
A2 B2 |-> 变换规则
... .../
所有字符串长度的上限为 20。
输出格式
若在 10 步(包含 10 步)以内能将 A 变换为 B,则输出最少的变换步数;否则输出 NO ANSWER!
输入输出样例
输入 #1
abcd xyz
abc xu
ud y
y yz
输出 #1
3
思路:bfs,当当前字符串存在sa[i]中的字符子串时,换成对应位置的sb[i]压入队列中,注意当前字符串可能有多个位置存在sa[i]中的字符字串,所以要搞个循环来判断一下
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Scanner;
import java.io.*;
public class Main {
static String[]sa = new String[6];
static String[]sb = new String[6];
public int bfs(String a, String b, int step,int n) {
Map<String, Integer>mp = new HashMap();
int ans = 20;
Queue<String>queue = new LinkedList<String>();
Queue<Integer>q2 = new LinkedList<Integer>();
queue.offer(a);
q2.offer(0);
//遍历所有的变换规则
while(!queue.isEmpty()) {
String s = queue.poll();
int bs = q2.poll();
if(s.equals(b)){
ans = Math.min(bs, ans);
break;
}
if(!mp.containsKey(s)) {//如果还没出现过,出现次数为1
mp.put(s, 1);
}else
continue;
if(bs > 10)
break;
for(int i = 0; i < n; i++) {
//如果当前的字串A1可以变成B1,那就变一下,如果a长度小于sa[i]用indexof的时候会出错
if(s.length() < sa[i].length())
continue;
//相同一段多次出现
int pos = 0;
while(s.indexOf(sa[i], pos) != -1) {
pos = s.indexOf(sa[i], pos);//sa[i]在a中出现的起始位置
String str = s.substring(0, pos) + sb[i] + s.substring(pos + sa[i].length());
queue.offer(str);
q2.offer(bs+1);
pos ++;
}
}
}
return ans;
}
public static void main(String[] args){
Scanner in = new Scanner(System.in);
String a = in.nextLine();
String b = a.substring(a.indexOf(" ") + 1);
a = a.substring(0, a.indexOf(" "));
int i = 0;
while(in.hasNext()) {
String s = in.nextLine();
sa[i] = s.substring(0, s.indexOf(" "));
sb[i++] = s.substring(s.indexOf(" ") + 1);
}
int min = new Main().bfs(a, b, 0, i);
if(min <= 10)
System.out.print(min);
else System.out.print("NO ANSWER!");
}
}