DFS,BFS打印可走路径

 

/**
      problem: 给定一个n×m的迷宫矩阵,其中'*'代表墙壁,不可通过;而'.'代表平地,可以通过;
      S代表起点,T代表终点。移动过程中,当前位置为(x,y),且每次只能向上下左右
      (x,y+1),(x,y-1),(x+1,y),(x-1,y)的平地移动,求S到T的最短步数。

     其中迷宫矩阵如下S(2,4)  T(4,3):
     data:
         5 5
        .....
        .*.*.
        .*.*.
        .***.
        ....*
        2 2 4 3
*/

/**
    solution 1:BFS求出最短步数;
*/

/**
      problem: 给定一个n×m的迷宫矩阵,其中'*'代表墙壁,不可通过;而'.'代表平地,可以通过;
      S代表起点,T代表终点。移动过程中,当前位置为(x,y),且每次只能向上下左右
      (x,y+1),(x,y-1),(x+1,y),(x-1,y)的平地移动,求S到T的最短步数。

     其中迷宫矩阵如下S(2,4)  T(4,3):
     data:
         5 5
        .....
        .*.*.
        .*.*.
        .***.
        ....*
        2 2 4 3
*/

/**
    solution 1:BFS求出最短步数;
*/

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
struct Node
{
    int x,y;
    int step;
};
const int maxn=20;
char maze[maxn][maxn];
int inq[maxn][maxn]={0};
int m,n;
int X[4]={0,0,1,-1};
int Y[4]={1,-1,0,0};
bool judge(int x,int y);
int BFS(Node a,Node b);
int main()
{
    printf("输入的迷宫行数与列数:\n");
    scanf("%d%d",&n,&m);
    printf("输入%d行%d列元素:\n",n,m);
    for(int i=0;i<n;i++)
            scanf("%s",maze[i]);
    Node origin,end;
    printf("输入起点坐标,终点坐标:\n");
    scanf("%d%d%d%d",&origin.x,&origin.y,&end.x,&end.y);
    origin.step=0;
    int ans=BFS(origin,end);
    cout << ans <<endl;
    return 0;
}

bool judge(int x,int y)
{
    if(x>=n||x<0||y>=m||y<0)
        return 0;
    if(maze[x][y]=='*'||inq[x][y]==1)
        return 0;
    return 1;
}

int BFS(Node a,Node b)
{
    Node node;
    queue<Node> q;
    q.push(a);
    inq [a.x][a.y]=1;
    while(!q.empty())
    {
        Node top=q.front();
        q.pop();
        if(top.x==b.x&&top.y==b.y)
            return top.step;
        for(int i=0;i<4;i++)
        {
            int newx=top.x+X[i];
            int newy=top.y+Y[i];
            if(judge(newx,newy))
            {
                node.x=newx;
                node.y=newy;
                node.step=top.step+1;
                q.push(node);
                inq[newx][newy]=1;
            }
        }
    }
    return -1;
}

 

2)BFS找出一条通向终点的路,并打印输出。
 * \ 每次记录入队结点的前驱节点,最后到达终点时,可以逆序打印,也可以再用一个矩阵
     来存储入口到出口的路径;

/** \brief
 *
 * \ 2)BFS找出一条通向终点的路,并打印输出。
 * \ 每次记录入队结点的前驱节点,最后到达终点时,可以逆序打印,也可以再用一个矩阵
     来存储入口到出口的路径;
 *  data:
        5 6
        ......
        .*.*.*
        .*S*..
        ..**..
        ...T.*
        2 2 4 3
 */

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
struct Node
{
    int x,y;
    int step,pre;   //step为该结点走的步数,pre为上一个结点的下标
    Node(int _x,int _y) : x(_x),y(_y) {}
    Node(){}
} road[100]; //road并不是存储所有的结点,只存储入队的节点;
int qh=-1,qe=1; //qh为road的头结点,qe为roadde尾结点
const int maxn=20;
int hash_table[maxn][maxn]={0}; //记录一条正确道路的值,以便输出
char maze[maxn][maxn];  //输入的地图矩阵
int inq[maxn][maxn]={0};    //判断节点是否入队
int m,n;    //m行n列地图
int X[4]={0,0,1,-1};    //方向数组
int Y[4]={1,-1,0,0};
bool judge(int x,int y);    //该节点是否合法,能否通过
void BFS(Node a,Node b);
void out(); //输出一条正确的道路
int main()
{
    printf("输入的迷宫行数与列数:\n");
    scanf("%d%d",&n,&m);
    printf("输入%d行%d列元素:\n",n,m);
    for(int i=0;i<n;i++)
            scanf("%s",maze[i]);
    Node origin,end;
    printf("输入起点坐标,终点坐标:\n");
    scanf("%d%d%d%d",&origin.x,&origin.y,&end.x,&end.y);
    origin.step=0;
    BFS(origin,end);
    return 0;
}

bool judge(int x,int y)
{
    if(x>=n||x<0||y>=m||y<0)
        return 0;
    if(maze[x][y]=='*'||inq[x][y]==1)
        return 0;
    return 1;
}

void BFS(Node a,Node b)
{
    Node node;
    queue<Node> q;
    a.pre=qh;
    road[0]=a;
    q.push(a);
    inq [a.x][a.y]=1;
    while(!q.empty())
    {
        ++qh;
        Node top=q.front();
        q.pop();
        if(top.x==b.x&&top.y==b.y)
        {
            cout << "total steps: " << top.step << endl;
            out();
            return;
        }
        for(int i=0;i<4;i++)
        {
            int newx=top.x+X[i];
            int newy=top.y+Y[i];
            if(judge(newx,newy))
            {
                node=Node(newx,newy);
                node.step=top.step+1;
                node.pre=qh;
                road[qe++]=node;
                q.push(node);
                inq[newx][newy]=1;
            }
        }
    }
    cout << "impossible\n";
}

void out()
{
    int temp=qh;
    cout << "逆序输出迷宫的正确出口道路:\n";
    while(1)
    {
        hash_table[road[temp].x][road[temp].y]=1;
        cout << road[temp].x << ' '  << road[temp].y << endl;
        if(road[temp].pre==-1)
            break;
        temp=road[temp].pre;
    }
    cout << "正确道路的地图:\n";
    for(int  i=0;i<n;++i)
    {
        for(int j=0;j<m;++j)
            if(hash_table[i][j]==1)
                cout << "#";
            else
                cout << "$";
        cout << endl;
    }
}

/*  ***** DFS  ***** */
/*  用回溯打印出所有可以通过的结果  */

/*  ***** DFS  ***** */
/*  用回溯打印出所有可以通过的结果  */

#include <iostream>
#include <cstdio>
using namespace std;
struct Node
{
    int x,y;
    int step;
    Node(int newx,int newy):x(newx),y(newy){}
    Node()=default;
};
const int maxn=20;
char maze[maxn][maxn];
int vis[maxn][maxn]={0};
int m,n;
int X[4]={0,0,1,-1};
int Y[4]={1,-1,0,0};
bool judge(int x,int y);
int DFS(Node a,Node b,int depth);
void out();
int main()
{
    printf("输入的迷宫行数与列数:\n");
    scanf("%d%d",&n,&m);
    printf("输入%d行%d列元素:\n",n,m);
    for(int i=0;i<n;i++)
        scanf("%s",maze[i]);
    Node origin,end;
    printf("输入起点坐标,终点坐标:\n");
    scanf("%d%d%d%d",&origin.x,&origin.y,&end.x,&end.y);
    int sum=0;
    for(int i=0;i<n;++i)
        for(int j=0;j<m;++j)
        {
            if(maze[i][j]=='.')
                ++sum;
        }
    cout << sum << endl;
    origin.step=0;
    maze[origin.x][origin.y]='y';
    DFS(origin,end,0);
    cout << "\n以下为调试代码\n";
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<m;++j)
        {
            cout << maze[i][j] << ' ';
        }
        cout << endl;
    }

    int total=0;
    for(int i=0;i<n;++i)
        for(int j=0;j<m;++j)
        {
            if(maze[i][j]=='y')
                ++total;
        }
    cout << total << endl;
    return 0;
}


int DFS(Node a,Node b,int depth)
{
    int newx,newy;
    for(int i=0;i<4;++i)
    {
        newx=a.x+X[i];
        newy=a.y+Y[i];
        if(judge(newx,newy))
        {
            char ch=maze[newx][newy];
            maze[newx][newy]='y';
            Node temp(newx,newy);
            if(newx==b.x&&newy==b.y)
            {
                cout << "succend\n";
                out();
            }
            else
                DFS(temp,b,depth+1);
            maze[newx][newy]=ch;
        }
    }
    maze[a.x][a.y]='n';
}

void out()
{
    int total=0;
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<m;++j)
        {
            if(maze[i][j]=='y')
            {
                cout << 'V';
                ++total;
            }
            else
                cout << '*';
        }
        cout << endl;
    }
    cout << total-1 << endl;
}

bool judge(int x,int y)
{
    if(x>=m||x<0||y>=n||y<0)
        return 0;
    if(maze[x][y]=='T')
        return 1;
    if(maze[x][y]!='.')
        return 0;
    return 1;
}


/*
5 6
......
.*.*.*
.*S*..
..**..
...T.*
2 2 4 3
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值