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

啊,被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

猜你喜欢

转载自blog.csdn.net/Love_Irelia97/article/details/82528621
今日推荐