题目描述
2x3=6 个方格中放入 ABCDE 五个字母,右下角的那个格空着。如下图所示。
和空格子相邻的格子中的字母可以移动到空格中,比如,图中的 C 和 E 就可以移动,移动后的局面分别是:
A B
D E C
A B C
D E
为了表示方便,我们把 6 个格子中字母配置用一个串表示出来,比如上边的两种局面分别表示为:
AB*DEC
ABCD*E
题目的要求是:请编写程序,由用户输入若干表示局面的串,程序通过计算,输出是否能通过对初始状态经过若干次移动到达该状态。可以实现输出 1,否则输出 0。初始状态为:ABCDE*。
输入描述
先是一个整数 n,表示接下来有 n 行状态。
输出描述
程序输出 n 行 1 或 0。
输入输出样例
示例
输入
3
ABCDE*
AB*DEC
CAED*B
输出
1
1
0
运行限制
最大运行时间:1s
最大运行内存: 256M
代码:
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class 移动字母 {
static String end = "ABCDE*";//初始状态
static int[] dir = { -3, -1, 1, 3 };
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
for (int i = 0; i < n; i++) {
String start = scanner.next();
bfs(start);
}
}
private static void bfs(String start) {
Queue<String> queue = new LinkedList<>();
HashSet<String> set = new HashSet<>();
queue.offer(start);
set.add(start);
while (!queue.isEmpty()) {
int len = queue.size();
while (len-- > 0) {
String temp = queue.poll();
// 出口
if (temp.equals(end)) {
System.out.println(1);
return;
}
// 找空格位置
int index = temp.indexOf('*');
// 遍历四个方向
for (int i = 0; i < 4; i++) {
int newIndex = index + dir[i];
// 判断是否越界
if (newIndex < 0 || newIndex > temp.length() - 1) {
continue;
}
// 只能上下左右四个方向移动
if ((newIndex % 3 == index % 3) || (newIndex / 3 == index / 3)) {
// 交换
char[] tempChar = temp.toCharArray();
tempChar[index] = temp.charAt(newIndex);
tempChar[newIndex] = temp.charAt(index);
String s = new String(tempChar);
//错误写法
//String s = tempChar.toString();
// 判断该场景是否出现过
if (!set.contains(s)) {
set.add(s);
queue.offer(s);
}
}
}
}
}
System.out.println(0);
return;
}
}