迷宫问题/n*m方格阵电路布线问题

本文探讨了电路布线问题与迷宫路径搜索的相似性,通过深度优先搜索和回溯法解决布线问题,提供了C++实现代码,展示了从起点到终点的最短路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

啊,被FDU无住宿无补贴劝退了,985终究一场梦,只好拿起自己学校的教材了

我们这本教材比较经典的就是电路布线问题了,估计和这方面成果不错有点关系。其实我今天仔细看了看发现这不就是迷宫的路径搜索问题吗......主要的思想还是深度优先搜索、回溯法......

参考了教材上的做法以后,发现其实思路都差不多,只不过我和它的标记和存储方法不同。我的做法是,初始化时用-2标记障碍点,用-1标记可布线点,用0标记起点,其它的依然是使用队列来搜索可布线点,但使用栈来存储路径,这样输出时正好是从起点到终点。

#include <cstdio>
#include <queue>
#include <stack>
using namespace std;

const int NumOfNbr  = 4;	//四个方向搜索,根据需要可改成八方向
const int GridOfRow = 7;	//行
const int GridOfCol = 7;	//列
int grid[GridOfRow+2][GridOfCol+2];	//加两行墙便于操作

struct Position{
	int x;
	int y;
}dir[NumOfNbr] = { {-1,0},{0,-1},{1,0},{0,1} };	//上左下右

void showLayout()
{
	for(int i = 1; i <= GridOfRow; ++i){
		for(int j = 1; j <= GridOfCol; ++j){
			printf("%2d ", grid[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}
//	可布线点-1,障碍物-2,起点处0
void initGird(Position start)
{
	for(int i = 0; i <= GridOfRow+1; ++i)
		for(int j = 0; j <= GridOfCol+1; ++j){
			if( i==0 || j==0 || i==GridOfRow+1 || j==GridOfCol+1 )
				grid[i][j] = -2;
			else
				grid[i][j] = -1;
		}

	printf("请输入障碍物坐标点,输入\"0,0\"结束:\n");
	int x, y;
	while( scanf("%d,%d",&x,&y) && !(x==0&&y==0) ){
		if( (x<=0||x>GridOfRow) || (y<=0||y>GridOfCol) ){
			printf("超出布线范围!重新输入!\n");
			continue;
		}
		grid[x][y] = -2;
	}
	grid[start.x][start.y] = 0;	//起点处标记为0
}

int FindPath(Position start, Position end, stack<Position>& path)
{
	if( start.x==end.x && start.y==end.y )
		return 0;
	if(  (start.x<=0||start.x>GridOfRow) || (start.y<=0||start.y>GridOfCol) ||
	     (end.x<=0  ||end.x>GridOfRow)   || (end.y<=0  ||  end.y>GridOfCol) )
		return -1;

	initGird(start);
	showLayout();

	Position here = start, nby;
	queue<Position> que;
	bool isFind = false;
	//	深度搜索路径
	do{
		//	各个方向的点
		for(int i = 0; i < NumOfNbr; ++i)
		{
			nby.x = here.x + dir[i].x;
			nby.y = here.y + dir[i].y;
			//	可布线点
			if( grid[nby.x][nby.y] == -1 ){
				grid[nby.x][nby.y] = grid[here.x][here.y] + 1;
				if( nby.x==end.x && nby.y==end.y ){
					isFind = true;
					break;
				}
				que.push(nby);
			}
		}
		if( isFind )
			break;

		if( que.empty() )
			return -1;	//	找不到路径
		else{
			here = que.front();	//	弹出队首结点,继续搜索
			que.pop();
		}
	}while( true );

	//	回溯路径
	here = end;
	int pathLength = grid[end.x][end.y];
	for(int len = pathLength-1; len >= 0; --len){
		path.push(here);
		for(int i = 0; i < NumOfNbr; ++i){
			nby.x = here.x + dir[i].x;
			nby.y = here.y + dir[i].y;
			if( grid[nby.x][nby.y] == len )
				break;
		}
		grid[here.x][here.y] = 0;	//标记为0,便于观察最短路径
		here = nby;
	}
	path.push(here);	//别忘了补上起点
	showLayout();

	return pathLength;
}

int main(void)
{
	Position start = {3,2}, end = {4,6};
	stack<Position> path;

	int length = FindPath(start, end, path);
	printf("最短路径如下,长度为%d\n", length);
	while( !path.empty() ){
		Position p = path.top();
		path.pop();
		printf("(%d,%d)->", p.x, p.y);
	}

	return 0;
}

//For test
//1,3
//2,3
//2,4
//3,5
//4,4
//4,5
//5,5
//5,1
//6,1
//6,2
//6,3
//7,1
//7,2
//7,3
//0,0

程序在VC++ 6下顺利编译通过。 一、 实验目的: (1) 熟练掌握链栈的基本操作及应用。 (2) 利用链表作为栈的存储结构,设计实现一个求解迷宫的非递归程序。 二、实验内容: 【问题描述】 以一个m×n的长方表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对信任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。 【基本要求】 首先实现一个链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。求得的通路以三元组(i,j,d)的形式输出,其中:(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。如:对于下列数据的迷宫,输出的一条通路为:(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2),……。 【测试数据】 迷宫的测试数据如下:左上角(1,1)为入口,右下角(8,9)为出口。 1 2 3 4 5 6 7 8 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 1 0 1 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 0 1 1 1 0 0 0 0 0 0 以方形式输出迷宫及其通路。 输出: 请输入迷宫的长和宽:5 5 请输入迷宫内容: 0 1 1 0 0 0 0 1 1 0 1 0 0 1 1 1 0 0 1 0 1 1 0 0 0 迷宫的路径为 括号内的内容分别表示为(行坐标,列坐标,数字化方向,方向) (1,1,1,↓) (2,1,2,→) (2,2,1,↓) (3,2,1,↓) (4,2,2,→) (4,3,1,↓) (5,3,2,→) (5,4,2,→) (5,5,0,) 迷宫路径探索成功!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值