/*
*题目描述:
卡片换位
你玩过华容道的游戏吗?
这是个类似的,但更简单的游戏。
看下面 3 x 2 的格子
+---+---+---+
| A | * | * |
+---+---+---+
| B | | * |
+---+---+---+
在其中放5张牌,其中A代表关羽,B代表张飞,* 代表士兵。还有一个格子是空着的。你可以把一张牌移动到相邻的空格中去(对角不算相邻)。游戏的目标是:关羽和张飞交换位置,其它的牌随便在哪里都可以。
输入格式:输入两行6个字符表示当前的局面
输出格式:
一个整数,表示最少多少步,才能把AB换位(其它牌位置随意)
例如,输入:
* A
**B
程序应该输出:
17
再例如,输入:
A B
***
程序应该输出:
12
* */
*题目描述:
卡片换位
你玩过华容道的游戏吗?
这是个类似的,但更简单的游戏。
看下面 3 x 2 的格子
+---+---+---+
| A | * | * |
+---+---+---+
| B | | * |
+---+---+---+
在其中放5张牌,其中A代表关羽,B代表张飞,* 代表士兵。还有一个格子是空着的。你可以把一张牌移动到相邻的空格中去(对角不算相邻)。游戏的目标是:关羽和张飞交换位置,其它的牌随便在哪里都可以。
输入格式:输入两行6个字符表示当前的局面
输出格式:
一个整数,表示最少多少步,才能把AB换位(其它牌位置随意)
例如,输入:
* A
**B
程序应该输出:
17
再例如,输入:
A B
***
程序应该输出:
12
* */
刚看到 题目时想到的方法是BFS,先将原始的情况放入队列,然后取出比较,没有达到终止情况,从空位开始走一步,上下左右各一种情况,一共四种情况(当然,越界的可以忽略),将走一步的情况保存在队列中,然后依次取出比较,如果符合终止条件,则得到步数,因为是一步一步的情况比较,所以最先匹配到终止条件的一定是最少步数,如果不符合终止条件,继续从空格开始,上下左右走一步,放在队列后,所有循环大致是,从队列取出,比较,不符合就在取出的情况的基础上再走一步,然后再取出。。。然而我不是用这种方法的。。。
DFS方法就是从空格开始,上下左右来递归遍历,遇到终止情况则记录步数,跟原有步数比较,保证每次存储的都是最少的步数。
BFS是把每一步的所有情况保存起来,找到最少步数
DFS是遍历每一种能够到达终止条件的步数,取最小
其中有几个要点,
1、不必储存二维数组,只需保存A,B,和空格的 坐标即保存了整个局面
2、需要标记数组以免走回头路
3、标记数组在回来时需擦除,以保证另一种遍历方式可以遍历
4、方向向量数组保存每一个方向的x,y增量,方便每一次上下左右走
上代码:
public class huarongdao {
static class Gezi{
public int x;
public int y;
public Gezi() {
}
};
static int go[][]={{0,-1},{0,1},{-1,0},{1,0}};
static Gezi a;
static Gezi b;
static Gezi k;
static int minstep=10000000;
static int[][][][][][] vis;
public static void main(String[] args) throws IOException {
vis=new int[3][3][3][3][3][3];
a=new Gezi();
b=new Gezi();
k=new Gezi();
Scanner scanner=new Scanner(System.in);
for(int i=0;i<2;i++){
String string=scanner.next();
string.trim();
for(int j=0;j<3;j++){
if (string.charAt(j)=='A') {
a.x=i;
a.y=j;
}
if (string.charAt(j)=='B') {
b.x=i;
b.y=j;
}
if (string.charAt(j)=='#') {
k.x=i;
k.y=j;
}
}
}
dfs(a.x,a.y,b.x,b.y,k.x,k.y,0);
System.out.println(minstep);
}
private static void dfs(int ax,int ay,int bx,int by,int kx,int ky,int step) {
if (ax==b.x&&ay==b.y&&bx==a.x&&by==a.y) {
minstep=Math.min(minstep, step);
return;
}
/*
* A#B
***
* */
if(ax<0||ax>1||ay<0||ay>2){
return;
}
if(bx<0||bx>1||by<0||by>2){
return;
}
if(kx<0||kx>1||ky<0||ky>2){
return;
}
if (vis[ax][ay][bx][by][kx][ky]==1) {
return;
}
vis[ax][ay][bx][by][kx][ky]=1;
for(int i=0;i<4;i++){
int xx=kx+go[i][0];
int yy=ky+go[i][1];
if(xx==ax&&yy==ay){
dfs(kx, ky, bx, by, xx, yy, step+1);
}
else {
if(xx==bx&&yy==by){
dfs(ax, ay, kx, ky, xx, yy, step+1);
}
else{
dfs(ax, ay, bx, by, xx, yy, step+1);
}
}
}
vis[ax][ay][bx][by][kx][ky]=0;
}
}