搜索+保存路径

我们先从一个简单的例题开始。
在这里插入图片描述

https://blog.csdn.net/wanglinlin_bfcx/article/details/75797529一个大佬简洁的写法。

这道题可以用广搜也可以用深搜,先说深搜吧
无非就是保存路径麻烦一点。我们可以这样,在函数体参数中加入一个数组,保存当前走过的路径。走到终点时,如果比原来路径短,就赋值给记录最终结果的全局变量数组里。当然要注意的一点是,函数体里无法直接改变形参,所以我另外用了pos数组中转,具体请看代码。

#include <bits/stdc++.h>
using namespace std;
int a[10][10];
int ans,b[5]={0,0,1,-1},c[5]={1,-1,0,0},vis[10][10];
int temp[50][10];
void dfs(int x,int y,int sumn,int lu[][10])
{
	if(x==4&&y==4)
	{
		if(sumn<ans)
		{
			for(int i=0;i<sumn;i++)
			{
			 	temp[i][0]=lu[i][0];
				temp[i][1]=lu[i][1];
			} 
			ans=sumn;
		}
		return;
	}
	int pos[50][10];//中转数组
	for(int j=0;j<=sumn;j++)
	{
		pos[j][0]=lu[j][0];
		pos[j][1]=lu[j][1];	
	} 
	for(int i=0;i<4;i++)
	{
		int xx=x+b[i],yy=y+c[i];
		if(xx>=0&&yy>=0&&xx<5&&yy<5&&vis[xx][yy]==0&&a[xx][yy]==0)
		{
			vis[xx][yy]=1;
			pos[sumn+1][0]=xx;pos[sumn+1][1]=yy;
			dfs(xx,yy,sumn+1,pos);
		//	vis[xx][yy]=0;//确实是可以不回溯的
		}
	}
}
int main()
{
	for(int i=0;i<5;i++)
	{
		for(int j=0;j<5;j++)
		{
			cin>>a[i][j];
		}
	}
	ans=999;
	int z[50][10];
	memset(z,0,sizeof(z));
	dfs(0,0,0,z);
	for(int i=0;i<ans;i++)
	{
		cout<<"("<<temp[i][0]<<", "<<temp[i][1]<<")"<<endl;
	}
	cout<<"("<<4<<", "<<4<<")"<<endl;
}

然后是广搜。
广搜的话就比较巧妙了,它另外开了一个数组记录路径,核心就是这条语句。
在这里插入图片描述
这条语句是在新节点temp入队列后紧接着执行的语句。
有了这条语句,因为我们已知终点位置,所以终点的上一个位置就是cnt[终点.x] [终点.y]。由于每次我们都是这么记录的,所以以上一个位置作为索引,可以得到上上个位置的值,这个仔细想想就好理解了。

#include <bits/stdc++.h>
using namespace std;
struct p
{
	int x,y;
}cnt[100][100];
queue<p> a;
int b[10][10],vis[10][10];
int c[5]={0,0,1,-1},d[5]={1,-1,0,0};
void bfs()
{
	p init;
	init.x=0;init.y=0;
	a.push(init);
	vis[0][0]=1;
	while(!a.empty())
	{
		p ans;
		ans=a.front();
		if(ans.x==4&&ans.y==4)
			return;
		a.pop();
		for(int i=0;i<4;i++)
		{
			p temp;
			temp.x=ans.x+c[i];temp.y=ans.y+d[i];
			if(temp.x>=0&&temp.y>=0&&temp.x<5&&temp.y<5&&b[temp.x][temp.y]==0&&vis[temp.x][temp.y]==0)
			{
				vis[temp.x][temp.y]=1;
				a.push(temp);
			//	cnt[ans.x][ans.y]=temp;//这里不要搞混了!
				cnt[temp.x][temp.y]=ans;	
			}	
		}
	} 
}
int main()
{
	for(int i=0;i<5;i++)
	{
		for(int j=0;j<5;j++)
			cin>>b[i][j];
	}
	bfs();
	p lll[50];//数组储存路径
	p ff=cnt[4][4];
	int k=0;
	while(!(ff.x==0&&ff.y==0))
	{
		lll[k]=ff;
		ff=cnt[ff.x][ff.y];
		k++;
	}
	cout<<"(0, 0)"<<endl;
	for(int i=k-1;i>=0;i--)//倒序输出
		cout<<"("<<lll[i].x<<", "<<lll[i].y<<")"<<endl;
/*	stack<p>v;//注释部分是用栈实现的
    p ff = cnt[4][4];
    while(!(ff.x==0&&ff.y==0)){
        v.push(ff);
        ff = cnt[ff.x][ff.y];
    }
    printf("(0, 0)\n");
    while(!v.empty()){
        printf("(%d, %d)\n",v.top().x,v.top().y);
        v.pop();
    }*/
    printf("(4, 4)\n");
    return 0;
}
posted @ 2019-12-15 16:24  倾叶子佮  阅读(214)  评论(0编辑  收藏  举报