zoukankan      html  css  js  c++  java
  • 洛谷P1238 走迷宫

    题目描述

    有一个m*n格的迷宫(表示有m行、n列),其中有可走的也有不可走的,如果用1表示可以走,0表示不可以走,文件读入这m*n个数据和起始点、结束点(起始点和结束点都是用两个数据来描述的,分别表示这个点的行号和列号)。现在要你编程找出所有可行的道路,要求所走的路中没有重复的点,走时只能是上下左右四个方向。如果一条路都不可行,则输出相应信息(用-1表示无路)。

    优先顺序:左上右下

    输入格式

    第一行是两个数m,n(1<m,n<15),接下来是m行n列由1和0组成的数据,最后两行是起始点和结束点。

    输出格式

    所有可行的路径,描述一个点时用(x,y)的形式,除开始点外,其他的都要用“一>”表示方向。

    如果没有一条可行的路则输出-1。

    输入输出样例

    输入 #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
    1 1
    5 6
    输出 #1
    (1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(2,5)->(3,5)->(3,4)->(3,3)->(4,3)->(4,4)->(4,5)->(5,5)->(5,6)
    (1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(2,5)->(3,5)->(3,4)->(4,4)->(4,5)->(5,5)->(5,6)
    (1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(2,5)->(3,5)->(4,5)->(5,5)->(5,6)
    (1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(3,3)->(4,3)->(4,4)->(4,5)->(5,5)->(5,6)
    (1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(3,5)->(4,5)->(5,5)->(5,6)
    (1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(4,4)->(4,5)->(5,5)->(5,6)
    (1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(3,4)->(2,4)->(2,5)->(3,5)->(4,5)->(5,5)->(5,6)
    (1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(3,4)->(3,5)->(4,5)->(5,5)->(5,6)
    (1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(3,4)->(4,4)->(4,5)->(5,5)->(5,6)
    (1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(4,3)->(4,4)->(3,4)->(2,4)->(2,5)->(3,5)->(4,5)->(5,5)->(5,6)
    (1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(4,3)->(4,4)->(3,4)->(3,5)->(4,5)->(5,5)->(5,6)
    (1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(4,3)->(4,4)->(4,5)->(5,5)->(5,6)


    思路:就是一个深搜,不过要记录前面从哪里走来的,那么只需要开一个pre数组来记录前面的坐标即可。pre[i][j][0]记录点(i,j)前一个点的横坐标,pre[i][j][1]则记录纵坐标。

    代码:
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int m,n,sx,sy,lx,ly,f;
    int dy[5]={0,-1,0,1,0};//这里是最细节的地方,因为在这种行列的矩阵里,经常会出现或者是大部分都是x表示纵坐标而y表示横坐标,但是我忽略了这一点,由于这个题要求优先级了,所以顺序不对是不行的。经过大佬fys的指点,我才成功地A了这个题,所以这个时候就要把x和y的数组换一下,左边就是y-1,而下边则是x+1,这里又是一个细节,因为左上角的点是(1,1),所以往下走其实纵坐标(x)要+1,往上走则要-1
    int dx[5]={0,0,-1,0,1};
    int a[20][20];
    int pre[20][20][2];
    void print(int x0,int y0)
    {
        if(pre[x0][y0][0]!=sx||pre[x0][y0][1]!=sy)//由于第一个起点也要输出但是前面没有箭头,所以要特别输出,不能在这个函数里,所以第二个点的时候就停止 print(pre[x0][y0][0],pre[x0][y0][1]);//如果它前面还有点的话,那么继续递归。一定要先递归再输出,这样才能从第一个点从前往后输出
        cout<<"-"<<">"<<"("<<x0<<","<<y0<<")";//print函数用来输出结果
    }
    void dfs(int x1,int y1)
    {
        if(x1==lx&&y1==ly)
        {
            f=1;//f用来判断有没有路径到达终点,如果没有输出-1
            cout<<"("<<sx<<","<<sy<<")";//如果找到了这个点,那么输出并且特别输出起点
            print(lx,ly);
            cout<<endl;//输出回车别忘了
            return;
        }
        a[x1][y1]=0;
        for(int i=1;i<=4;i++)
        {
            int x=x1+dx[i];
            int y=y1+dy[i];
            if(a[x][y]==1&&x>=1&&x<=n&&y>=1&&y<=m)
            {
                a[x][y]=0;
                pre[x][y][0]=x1;
                pre[x][y][1]=y1;
                dfs(x,y);
                a[x][y]=1;//这就是当初我死活都学不会的回溯,每次递归完之后你要把它恢复原状,以便下一次搜索时还是初始状态
                pre[x][y][0]=0;
                pre[x][y][1]=0;
            }
        }
    }
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                cin>>a[i][j];
        cin>>sx>>sy>>lx>>ly;
        if(a[sx][sy]==0||a[lx][ly]==0)
        {
            cout<<-1<<endl;
            return 0;
        }
        dfs(sx,sy);//搜索
        if(f==0)//如果没有到达终点,那么输出-1
            cout<<-1<<endl;
        return 0;
    }
  • 相关阅读:
    工作中遇到的java 内存溢出,问题排查
    java线上内存溢出问题排查步骤
    性能测试-java内存溢出问题排查
    164 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 04 终止finally执行的方法
    163 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 03 使用多重catch结构处理异常
    162 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 02 使用try-catch结构处理异常
    161 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 01 try-catch-finally简介
    160 01 Android 零基础入门 03 Java常用工具类01 Java异常 03 异常处理简介 01 异常处理分类
    159 01 Android 零基础入门 03 Java常用工具类01 Java异常 02 异常概述 02 异常分类
    158 01 Android 零基础入门 03 Java常用工具类01 Java异常 02 异常概述 01 什么是异常?
  • 原文地址:https://www.cnblogs.com/57xmz/p/13038960.html
Copyright © 2011-2022 走看看