蓝桥杯2016年初赛 卡片换位Java

题目:卡片换位

你玩过华容道的游戏吗?
这是个类似的,但更简单的游戏。
看下面 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;//步数
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值