【ACM】【DFS】深搜打印所有经过的路径、打印最短路径

7 篇文章 0 订阅

题目:给定一个大小为N*M的迷宫。迷宫由通道和墙壁组成,每一步可以向邻接的上下左右四个方向移动,请打印出所有能够到达目的地的路径。

样例输入:     // “ S ” 表示起点、“ G ”表示重点、“ . ”表示通道、“ # ”表示墙壁

10 10
#S######.#
......#..#
.#.##.##.#
.#........
##.##.####
....#....#
.#######.#
....#.....
.####.###.
....#...G#

样例输出:(有点长)

********************路径1********************
( 2 , 2 )
( 2 , 3 )
( 2 , 4 )
( 2 , 5 )
( 2 , 6 )
( 3 , 6 )
( 4 , 6 )
( 5 , 6 )
( 6 , 6 )
( 6 , 7 )
( 6 , 8 )
( 6 , 9 )
( 7 , 9 )
( 8 , 9 )
( 8 , 8 )
( 8 , 7 )
( 8 , 6 )
( 9 , 6 )
( 10 , 6 )
( 10 , 7 )
( 10 , 8 )
( 10 , 9 )
********************路径2********************
( 2 , 2 )
( 2 , 3 )
( 3 , 3 )
( 4 , 3 )
( 4 , 4 )
( 4 , 5 )
( 4 , 6 )
( 5 , 6 )
( 6 , 6 )
( 6 , 7 )
( 6 , 8 )
( 6 , 9 )
( 7 , 9 )
( 8 , 9 )
( 8 , 8 )
( 8 , 7 )
( 8 , 6 )
( 9 , 6 )
( 10 , 6 )
( 10 , 7 )
( 10 , 8 )
( 10 , 9 )

 解题思路:

遍历整个迷宫、定义两个栈存放临时路径坐标和一个空的组用来输出。然后大致思路就是DFS。

代码如下:

#include<iostream>
#include<queue>
#include<stack>
#define MAXN 51
using namespace std;

struct node{
	int x,y;
}p;

stack<node> path,temp;
int n,m;
int sx,sy,ex,ey;
char map[MAXN][MAXN];
bool book[MAXN][MAXN]={false};
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int count=0;

void dfs(int x,int y)
{	
	for(int i=0;i<4;i++)
	{
		int gx=x+next[i][0];
		int gy=y+next[i][1];
		if(gx==ex&&gy==ey)
		{
	                cout << "********************路径" << ++count << "********************\n";
			//将path里面的点取出来,放在temp里面 
			while(!path.empty())
			{
				//path从栈顶到栈底方向,路径是从终点到起点的方向
				node p1=path.top();
				path.pop();
				temp.push(p1); 
			}
			while(!temp.empty())
			{					
				//输出temp里面所有的路径  这样正好是从起点到终点的方向
				node p1=temp.top();
				temp.pop();
				path.push(p1);		//存放在path里面因为后面还要回溯
				cout << "( " << p1.x << " , " << p1.y << " )\n";  
			}
			cout << "( " << ex << " , " << ey << " )\n"; 
			return;
		}			
		if(gx<1||gx>n||gy<1||gy>m)
			continue;
		if(book[gx][gy]==false&&map[gx][gy]=='.')
		{
			book[gx][gy]=true;
			p.x=gx;
			p.y=gy;
			path.push(p);			
			dfs(gx,gy);
			//回溯 
			book[gx][gy]=false;
			path.pop();
		}
	}
	return;
}

int main()
{
	cin >> n >> m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			cin >> map[i][j];
			if(map[i][j]=='S')
				sx=i,sy=j;
			if(map[i][j]=='G')
				ex=i,ey=j;
		}	
	dfs(sx,sy);	
	return 0;
}

还是上述题目的条件,输入不变,输出只输出最短路径。

样例输出:

(2,2)
(2,3)
(3,3)
(4,3)
(4,4)
(4,5)
(4,6)
(5,6)
(6,6)
(6,7)
(6,8)
(6,9)
(7,9)
(8,9)
(8,8)
(8,7)
(8,6)
(9,6)
(10,6)
(10,7)
(10,8)
(10,9)

解题思路:

添加一个Mtemp栈用来存最短路径、每次都做对比、最后直接输出Mtemp栈。

代码如下:

#include<iostream>
#include<queue>
#include<stack>
#define MAXN 51
using namespace std;

struct node{
	int x,y;
}p;

stack<node> path,temp,Mtemp;
int minn=9999999;
int n,m;
int sx,sy,ex,ey;
char map[MAXN][MAXN];
bool book[MAXN][MAXN]={false};
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int count=0;

void dfs(int x,int y,int step)
{	
	for(int i=0;i<4;i++)
	{
		int gx=x+next[i][0];
		int gy=y+next[i][1];
		if(gx==ex&&gy==ey)
		{
			if(step<minn)	//若小于最小路径、把路径存入 栈temp 
			{
				while(!temp.empty())
					temp.pop();
				while(!Mtemp.empty())
					Mtemp.pop();
				while(!path.empty())
				{
					node p1=path.top();
					temp.push(p1);
					Mtemp.push(p1);
					path.pop();	
				} 
				while(!temp.empty())
				{
					node p1=temp.top();
					path.push(p1);
					temp.pop();
				}
			} 
		}			
		if(gx<1||gx>n||gy<1||gy>m)
			continue;
		if(book[gx][gy]==false&&map[gx][gy]=='.')
		{
			book[gx][gy]=true;
			p.x=gx;
			p.y=gy;
			path.push(p);		
			dfs(gx,gy,step+1);
			//回溯 
			book[gx][gy]=false;
			path.pop();
		}
	}
	return;
}

int main()
{
	cin >> n >> m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			cin >> map[i][j];
			if(map[i][j]=='S')
				sx=i,sy=j;
			if(map[i][j]=='G')
				ex=i,ey=j;
		}	
	dfs(sx,sy,0);	
	while(!Mtemp.empty())
	{
		p=Mtemp.top();
		cout << "(" << p.x << "," << p.y << ")\n";
		Mtemp.pop();
	}
	cout << "(" << ex << "," << ey << ")\n"; 
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值