题目:卡片换位
你玩过华容道的游戏吗?
这是个类似的,但更简单的游戏。
看下面 3 x 2 的格子
+---+---+---+
| A | * | * |
+---+---+---+
| B | | * |
+---+---+---+
在其中放5张牌,其中A代表关羽,B代表张飞,* 代表士兵。
还有一个格子是空着的。
你可以把一张牌移动到相邻的空格中去(对角不算相邻)。
游戏的目标是:关羽和张飞交换位置,其它的牌随便在哪里都可以。
输入格式:
输入两行6个字符表示当前的局面
输出格式:
一个整数,表示最少多少步,才能把AB换位(其它牌位置随意)
例如,输入:
* A
**B
程序应该输出:
17
再例如,输入:
A B
***
程序应该输出:
12
思路:
状态的变化,求最小步数一般是使用bfs算法。将二维字符数组转化为一维字符串,然后进行判断处理。
package Java2016;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
public class 卡片换位 {
static String s;//初始状态
static int posA;//A的位置
static int posB;//B的位置
static O posO;//空格的位置
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String s1=sc.nextLine();
String s2=sc.nextLine();
s=s1+s2;
char[][] a=new char[2][3];
for (int i = 0; i < a[0].length; i++) {
a[0][i]=s1.charAt(i);
}
for (int i = 0; i < a[0].length; i++) {
a[1][i]=s2.charAt(i);
}
posO=new O();
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[0].length; j++) {
if (a[i][j]=='A') {
posA=3*i+j;
}
if (a[i][j]=='B') {
posB=3*i+j;
}
if (a[i][j]==' ') {
posO.i=i;
posO.j=j;
}
}
}
bfs();
}
public static void bfs() {
Queue<T> q=new LinkedList<T>();
T t=new T(posO,s);
HashSet<String> set=new HashSet<>();
set.add(s);
q.add(t);
while(!q.isEmpty()) {
T t1=q.poll();
if (check(t1.s)) {
System.out.println(t1.num);
return;
}
int i=t1.x.i;
int j=t1.x.j;
if (i-1>=0) {
int x1=(i-1)*3+j;
int x2=i*3+j;
String s1=swap(t1.s,x1,x2);
if (set.add(s1)) {
O o1=new O();
o1.i=i-1;
o1.j=j;
T t2=new T(o1,s1);
t2.num=t1.num+1;
q.offer(t2);
}
}
if (i+1<2) {
int x1=(i+1)*3+j;
int x2=i*3+j;
String s1=swap(t1.s,x1,x2);
if (set.add(s1)) {
O o1=new O();
o1.i=i+1;
o1.j=j;
T t2=new T(o1,s1);
t2.num=t1.num+1;
q.offer(t2);
}
}
if (j-1>=0) {
int x1=(i)*3+j-1;
int x2=i*3+j;
String s1=swap(t1.s,x1,x2);
if (set.add(s1)) {
O o1=new O();
o1.i=i;
o1.j=j-1;
T t2=new T(o1,s1);
t2.num=t1.num+1;
q.offer(t2);
}
}
if (j+1<3) {
int x1=(i)*3+j+1;
int x2=i*3+j;
String s1=swap(t1.s,x1,x2);
if (set.add(s1)) {
O o1=new O();
o1.i=i;
o1.j=j+1;
T t2=new T(o1,s1);
t2.num=t1.num+1;
q.offer(t2);
}
}
}
}
public static boolean check(String s) {
//判断是否达到最终状态
int x=0,y=0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i)=='A') {
x=i;
}
if (s.charAt(i)=='B') {
y=i;
}
}
if(x==posB&&y==posA) {
return true;
}
return false;
}
public static String swap(String s,int i,int j) {
//交换位置
char[] c=s.toCharArray();
char e=c[i];
c[i]=c[j];
c[j]=e;
return new String(c);
}
}
class O{
//记录空格坐标
int i;
int j;
}
class T{
//保存状态
O x=new O();//记录空格的位置
String s;//矩阵的状态
public T(O i,String s) {
this.s=s;
this.x.i=i.i;
this.x.j=i.j;
}
int num;//步数
}