走迷宫--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;

}
原文地址:https://www.cnblogs.com/-citywall123/p/10473452.html