3148: 搜索基础之迷宫问题
从起点开始遍历,上下左右四个方向,如果找到了能走的方向,从这个方向再往下走,没找到说明走到这个点走到了一个死胡同,这个点需要回退。
按上面的算法,保存在栈中的就是所有路径。
因为有上下左右四个方向,如果找到一个,就不要再继续找这个点的其他方向了,而是将这个新找到的点入栈,再从这个点出发去DFS其他点。
每找到一个点,需要设置这个点不能走了,可以将这个点设置为墙。因为这个点走也是死胡同,所以把这个点设置为墙下次再走的时候就不要走了,如果将这个点在重新设置为0 (可以走),就会死循环。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
typedef pair<int,int> PII;
const int N = 10;
int fx[N] = {0,-1,0,1};
int fy[N] = {1,0,-1,0};
int a[10][10];
PII res[100];
int xe,ye;
stack<PII> s;
void print()
{
int k=0;
while(!s.empty())
{
PII top = s.top();
s.pop();
res[++k] = {top.first,top.second};
}
for(int i=k;i>0;i--)
cout<<"("<<res[i].first-1<<", "<<res[i].second-1<<")\n";
}
void dfs()
{
s.push({1,1});
a[1][1] = -1;
while(!s.empty())
{
PII top;
top = s.top();
int x0,y0;
x0=top.first;
y0=top.second;
bool find = false;
for(int i=0;i<4 &&!find;i++)
{
int x,y;
x = x0 + fx[i];
y = y0 + fy[i];
if(x<1||y<1||x>5||y>5||a[x][y])
continue;
find = true;
a[x][y] = 1;
s.push({x,y});
if(x==xe&&y==ye)
{
print();
}
}
if(!find)
{
s.pop();
}
}
}
int main()
{
int n=5;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
cin>>a[i][j];
}
xe = ye = 5;
dfs();
}
用递归做
建议反复观看
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
typedef pair<int,int> PII;
const int N = 10;
int a[N][N];
int fx[4] = {0,-1,0,1};
int fy[4] = {1,0,-1,0};
int n;
int xe = 4,ye=4;
stack<PII> s;
vector<PII>res;
void print()
{
while(!s.empty())
{
PII top = s.top();
s.pop();
int x=top.first;
int y=top.second;
res.push_back(top);
}
for(int i=res.size()-1;i>=0;i--)
cout<<"("<<res[i].first<<", "<<res[i].second<<")\n";
}
bool found = false;
void dfs(int x,int y)
{
if(x<0||y<0||x>4||y>4||a[x][y])
{
a[x][y] = 1;
return;
}
if(x==xe&&y==ye)
{
found = true;
return;
}
a[x][y] = 1;
for(int i=0;i<4 && ! found;i++) //如果没有这个 !found,就算已经找了出口也还会继续递归。!found是找到了之后就不要再找别的路径了。
{
int xto,yto;
xto = x+fx[i];
yto = y+fy[i];
dfs(xto,yto);
if(found) res.push_back({xto,yto});
}
}
int main()
{
n=5;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>a[i][j];
dfs(0,0);
cout<<"(0, 0)\n";
for(int i=res.size()-1;i>=0;i--)
cout<<"("<<res[i].first<<", "<<res[i].second<<")\n";
}