走迷宫--DFS
走迷宫
【问题描述】
有一个m*n格的迷宫(表示有m行、n列),其中有可走的也有不可走的,如果用1表示可以走,0表示不可以走,文件读入这m*n个数据和起始点、结束点(起始点和结束点都是用两个数据来描述的,分别表示这个点的行号和列号)。现在要你分别编程4个程序解决以下4个问题。
问题1:找出所有可行的道路,要求所走的路中没有重复的点,走时只能是上下左右四个方向。如果一条路都不可行,则输出相应信息(用-l表示无路)。
问题2:求最少需要几步可以从起始点到达结束点。
问题3:求从起始点到达结束点的一条最短路径。
问题4:求从起始点到达结束点的所有最短路径。
【输入】
第一行是两个数m,n(1<m,n<15),接下来是m行n列由1和0组成的数据,起点从(0,0)开始,最后一行输入结束点(n1,m1)。
【输出】
问题1:所有可行的路径,描述一个点时用(x,y)的形式,除开始点外,其他的都要用“一>”表示方向。如果没有一条可行的路则输出-1。
……
【样例】
5 6
1 0 0 1 0 1
1 1 1 1 1 1
0 0 1 1 1 0
1 1 1 1 1 0
1 1 1 0 1 1
【输出样例】
case#: 1
(0,0)->(1,0)->(1,1)->(1,2)->(1,3)->(1,4)->(2,4)->(2,3)->(2,2)->(3,2)->(3,3)->(3,4)->(4,4)->(4,5)
case#: 2
(0,0)->(1,0)->(1,1)->(1,2)->(1,3)->(1,4)->(2,4)->(2,3)->(3,3)->(3,4)->(4,4)->(4,5)
case#: 3
(0,0)->(1,0)->(1,1)->(1,2)->(1,3)->(1,4)->(2,4)->(3,4)->(4,4)->(4,5)
case#: 4
(0,0)->(1,0)->(1,1)->(1,2)->(1,3)->(2,3)->(2,4)->(3,4)->(4,4)->(4,5)
case#: 5
(0,0)->(1,0)->(1,1)->(1,2)->(1,3)->(2,3)->(2,2)->(3,2)->(3,3)->(3,4)->(4,4)->(4,5)
case#: 6
(0,0)->(1,0)->(1,1)->(1,2)->(1,3)->(2,3)->(3,3)->(3,4)->(4,4)->(4,5)
case#: 7
(0,0)->(1,0)->(1,1)->(1,2)->(2,2)->(2,3)->(2,4)->(3,4)->(4,4)->(4,5)
case#: 8
(0,0)->(1,0)->(1,1)->(1,2)->(2,2)->(2,3)->(3,3)->(3,4)->(4,4)->(4,5)
case#: 9
(0,0)->(1,0)->(1,1)->(1,2)->(2,2)->(2,3)->(1,3)->(1,4)->(2,4)->(3,4)->(4,4)->(4,5)
case#: 10
(0,0)->(1,0)->(1,1)->(1,2)->(2,2)->(3,2)->(3,3)->(3,4)->(4,4)->(4,5)
case#: 11
(0,0)->(1,0)->(1,1)->(1,2)->(2,2)->(3,2)->(3,3)->(2,3)->(2,4)->(3,4)->(4,4)->(4,5)
case#: 12
(0,0)->(1,0)->(1,1)->(1,2)->(2,2)->(3,2)->(3,3)->(2,3)->(1,3)->(1,4)->(2,4)->(3,4)->(4,4)->(4,5)
先解决问题4:输出所有的可行路径
#include<iostream> #include<stdio.h> #include<string.h> #define minx 0x3f3f3f3f using namespace std; int n,m,n1,m1,cnt=0,shortest=minx; int vis[100][100],map[100][100]; int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int flag=0; struct node { int x; int y; int dep; }way[1000]; struct node1 { int x; int y; int len; }way1[3];//记录最短路径 int check(int x,int y) { if(x>=0&&x<n&&y>=0&&y<m) return 1; else return 0; } void dfs(int x,int y,int dep) { if(x==n1-1&&y==m1-1) { flag=1; cnt++; cout<<"case#: "<<cnt<<endl; cout<<"(0,0)->"; for(int i=0;i<dep&&i!=dep-1;i++) { cout<<'('<<way[i].x<<','<<way[i].y<<')'<<"->"; } cout<<'('<<way[dep-1].x<<','<<way[dep-1].y<<')'<<endl; // if(dep<shortest) // { // shortest=dep; // for(int i=0;i<shortest;i++) // { // way1[i].x=way[i].x; // way1[i].y=way[i].y; // } // } } else { int tx,ty; for(int i=0;i<4;i++) { tx=x+dir[i][1]; ty=y+dir[i][0]; if(check(tx,ty)&&!vis[tx][ty]&&map[tx][ty]) { way[dep].x=tx; way[dep].y=ty; vis[tx][ty]=1; dfs(tx,ty,dep+1); vis[tx][ty]=0; } } } } int main() { cin>>n>>m; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { cin>>map[i][j]; } } cin>>n1>>m1; dfs(0,0,0); if(flag==0) cout<<"-1"<<endl; // cout<<"(0,0)->"; // for(int i=0;i<shortest&&i!=shortest-1;i++) // { // cout<<'('<<way1[i].x<<","<<way1[i].y<<')'<<"->"; // } // cout<<'('<<way1[shortest-1].x<<','<<way1[shortest-1].y<<')'<<endl; return 0; }
在解决问题3和4:输出到达终点的一条最短路径和最少步骤数
#include<iostream> #include<stdio.h> #include<string.h> #define minx 0x3f3f3f3f using namespace std; int n,m,n1,m1,cnt=0,shortest=minx; int vis[100][100],map[100][100]; int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int flag=0; struct node { int x; int y; int dep; }way[1000]; struct node1 { int x; int y; int len; }way1[3];//记录最短路径 int check(int x,int y) { if(x>=0&&x<n&&y>=0&&y<m) return 1; else return 0; } void dfs(int x,int y,int dep) { if(x==n1-1&&y==m1-1) { flag=1; // cnt++; // cout<<"case#: "<<cnt<<endl; // cout<<"(0,0)->"; // for(int i=0;i<dep&&i!=dep-1;i++) // { // cout<<'('<<way[i].x<<','<<way[i].y<<')'<<"->"; // } // cout<<'('<<way[dep-1].x<<','<<way[dep-1].y<<')'<<endl; if(dep<shortest) { shortest=dep; for(int i=0;i<shortest;i++) { way1[i].x=way[i].x; way1[i].y=way[i].y; } } } else { int tx,ty; for(int i=0;i<4;i++) { tx=x+dir[i][1]; ty=y+dir[i][0]; if(check(tx,ty)&&!vis[tx][ty]&&map[tx][ty]) { way[dep].x=tx; way[dep].y=ty; vis[tx][ty]=1; dfs(tx,ty,dep+1); vis[tx][ty]=0; } } } } int main() { cin>>n>>m; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { cin>>map[i][j]; } } cin>>n1>>m1; dfs(0,0,0); cout<<"(0,0)->"; for(int i=0;i<shortest&&i!=shortest-1;i++) { cout<<'('<<way1[i].x<<","<<way1[i].y<<')'<<"->"; } cout<<'('<<way1[shortest-1].x<<','<<way1[shortest-1].y<<')'<<endl; if(flag==0) cout<<"-1"<<endl; return 0; }
bfs求最短路
#include<iostream> #include<stdio.h> #include<queue> #include<string.h> using namespace std; int map[50][50], vis[50][50]; int dir[4][2] = { { 1,0 },{ -1,0 },{ 0,1 },{ 0,-1 } }; int n, m, flag = 0; struct node { int x; int y; int step; }; queue<node>q; node star, end2, now, next1, pre[20][20], way[300];//pre[x][y]表示坐标为(x,y)的上一个节点 int inbord(int x, int y) //now是当前节点,next1是下一个节点 { if (x >= 0 && x<n&&y >= 0 && y<m) return 1; else return 0; } void bfs(int x, int y) { while (!q.empty()) { now = q.front(); q.pop(); if (now.x == end2.x&&now.y == end2.y)//搜索到终点,输出 { cout <<"shortest: "<< now.step << endl; int cnt = 0; int xx = now.x, yy = now.y; next1.x = xx; next1.y = yy; while (xx != star.x || yy != star.y)//回溯 { way[cnt++] = next1; next1 = pre[next1.x][next1.y]; xx = next1.x; yy = next1.y; } cout << '(' << star.x << ',' << star.y << ')' << "->"; for (int i = cnt - 1; i >= 0; i--) { cout << '(' << way[i].x << ',' << way[i].y << ')'; if (i != 0) cout << "->"; } cout<<endl; flag = 1; break; } next1.step = now.step + 1; for (int i = 0; i<4; i++) { next1.x = now.x + dir[i][1]; next1.y = now.y + dir[i][0]; if (inbord(next1.x, next1.y) && !vis[next1.x][next1.y] && map[next1.x][next1.y]) { pre[next1.x][next1.y] = now; vis[next1.x][next1.y] = 1; q.push(next1); } } } } int main() { cin >> n >> m; for (int i = 0; i<n; i++) { for (int j = 0; j<m; j++) cin >> map[i][j]; } cin >> end2.x >> end2.y; star.x = 0; star.y = 0; star.step = 0; memset(vis, 0, sizeof(vis)); vis[star.x][star.y] = 1; q.push(star); bfs(star.x, star.y); if (flag == 0) cout << "-1" << endl; }