蓝桥杯 迷宫

//import java.util.Scanner;

public class Main {
int map[][] = new int[32][52];//迷宫数组(有加墙)
class Box {//方块内部类
int i;//方块的位置
int j;
int pre;//本路径中上一个方块在队列中的下标
Box(int i,int j,int pre) {
this.i = i;
this.j = j;
this.pre = pre;
}
void setBox(int i,int j,int pre) {//修改Box对象数据
this.i = i;
this.j = j;
this.pre = pre;
}
Box copyBox() {//返回一个Box对象的复制体
int i = this.i,j = this.j,pre = this.pre;
return new Box(i,j,pre);
}
}
class QuType {//顺序队列内部类
Box data[] = new Box[4000];//data数组要足够大
int front = -1;
int rear = -1;
void enQueue(Box box) {//入队
data[++rear] = box;
}
Box deQueue() {//出队
return data[++front].copyBox();
}
boolean queueEmpty() {//判断队列是否为空
return (front == rear);
}
}

public static void main(String[] args) {
	Scanner reader = new Scanner(System.in);
	Main main = new Main();
	main.initMap();
	main.reciveData();
	main.mappath(1, 1, 30, 50);
}

void initMap() {//初始化迷宫数组,给迷宫数组外面加一层围墙
	for (int i = 0; i < 32; i++) {
		if (i == 0 || i == 31) {
			for (int j = 0; j < 52; j++) {
				map[i][j] = 1;
			}
		}
		else {
			map[i][0] = map[i][51] = 1;
		}
	}
}
void reciveData() {//接收迷宫数据
	Scanner reader = new Scanner(System.in);
	for (int i = 1; i <= 30; i++) {
		char tMap[] = reader.nextLine().trim().toCharArray();
		for (int j = 1; j <= 50; j++) {
			map[i][j] = tMap[j-1] - '0';
		}
	}
}
boolean mappath(int xi,int yi,int xe,int ye) {//求从迷宫(xi,yi)到(xe,ye)的路线
	Box e = new Box(xi,yi,-1);
	QuType qu = new QuType();
	qu.enQueue(e.copyBox());//xi,yi进队
	map[xi][yi] = -1;//将其赋值为-1,以避免回过来重复搜素
	while (!qu.queueEmpty()) {//队列非空时循环
		e = qu.deQueue();//出队方块e,由于不是环形队列,该出队元素仍在队列中
		int i = e.i,j = e.j;
		int il = 0,jl = 0;
		if (i == xe && j == ye) {//找到了出口,输出路径
			print(qu);//调用函数print输出路径
			return true;//找到一条路径是返回真
		}
		for (int d = 0; d < 4; d++) {//循环扫描四个方位(按照D,L,R,U的字典序顺序扫描),把每个可走的方块插入到队列中
			switch(d) {
			case 0: il = i+1; jl = j; break;
			case 1: il = i; jl = j-1; break;
			case 2: il = i; jl = j+1; break;
			case 3: il = i-1; jl = j; break;
			}
			if (map[il][jl] == 0) {
				e.setBox(il, jl, qu.front);//qu.front指向上一个方块的下标
				qu.enQueue(e.copyBox());//(il,jl)方块入队
				map[il][jl] = -1;//将其赋值为-1,以避免回过来重复搜素
			}
		}
	}
	return false;//未找到任何路径时返回假
}
void print(QuType qu) {//输出路线
	int k = qu.front,j;
	do {//反向找最短路径,将该路径上的方块的pre成员设置为-1
		j = k;
		k = qu.data[k].pre;
		qu.data[j].pre = -1;
	}while (k != 0);
	k = 1;
	Box b1 = qu.data[0].copyBox();
	Box b2;
	while (k <= qu.front) {//正向搜索pre为-1的方块,通过与上一个pre为-1的方块比较,输出行走方向,最终输出正确路线
		if (qu.data[k].pre == -1) {
			b2 = qu.data[k].copyBox();
			int a = b2.i - b1.i, b = b2.j - b1.j;
			if (a == 1) {
				System.out.print("D");
			}
			else if (a == -1) {
				System.out.print("U");
			}
			else if (b == 1) {
				System.out.print("R");
			}
			else if (b == -1) {
				System.out.print("L");
			}
			b1 = b2;
		}
		k++;
	}
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值