zoukankan      html  css  js  c++  java
  • 【题解】(LGJ原创)蝴蝶旅客

    题目描述

    歌姬什么的,不干了啦!星尘要旅游!

    于是星尘换上了蝴蝶套装在一片为 (p) 层每层n行m列的矩阵中开始了她的旅行,她从 ((1,1,1)) 出发,到 ((x,y,z)) 去。这片空间里有一些是不能通过的,因为这些空间内没有以太之尘,星尘飞不起来。现在告诉你哪里有以太之尘,请你依照 (x) 轴正 ((x+1))(y) 轴正 ((y+1))(z) 轴正 ((z+1))(x) 轴负 ((x-1))(y) 轴负 ((y-1))(z) 轴负 ((z-1))的顺序找到到达终点的所有路径,

    对于每一条路径,不能走回头路,因为走过的路也没有以太之尘。记住,每条路径之间不会互相干扰,这一条走过某个位置不影响另一条路径走过这个位置。如果不能到达输出 (-1)

    输入格式

    第一行六个整数表示 (p) 层每层 (n)(m) 列和终点坐标 (x、y、z)
    接下来有 (p) 个矩阵,每个矩阵有 (n)(m) 列,(1) 表示可以通过。

    输出格式

    输出从起点到终点的所有路径,不存在输出 (-1)

    样例输入

    3 3 3 3 3 1

    1 1 1
    0 0 1
    0 0 1

    1 0 0
    0 0 0
    0 0 1

    1 1 1
    0 0 1
    0 0 1

    样例输出

    (1,1,1)->(1,2,1)->(1,3,1)->(2,3,1)->(3,3,1)
    (1,1,1)->(1,1,2)->(1,1,3)->(1,2,3)->(1,3,3)->(2,3,3)->(3,3,3)->(3,3,2)->(3,3,1)

    数据范围

    (n,m,ple 10)

    题目大意

    LGJ出的毒瘤搜索……但是这个……三维搜索……有(yi)点复杂啊……

    分析

    如果要输出路径的话就必须用深搜勒~ 但是,“在写这道题被 (TLE) 狂虐中我明白了,越是优化剪枝(其实并没有什么可剪的)抓耳挠腮,越会发现 (dfs) 的力量是有限的,除非超越 (dfs)。……所以……我用 (bfs) 辣!JOJO![哔——]”

    注意到如果根本无法到达终点的话,(dfs) 就会像无头苍蝇一样到处搜索,时间复杂度大大提高,所以,可以考虑先用 (bfs) 搜索一遍判断是否可以到达终点,如果不能直接输出 (-1) 结束程序,这样便使得 (dfs) 不会因为无法到达终点而时间超限。

    确定算法之后就来到了这道题最另人头秃的地方了:确定 (x、y、z)
    将样例画出来之后如下图所示:
    (黑色、蓝色、红色分别为不同的层)

    题目中的两条路径分别为:

    所以,题目中的坐标 ((x,y,z)) 指的是第 (x)(y)(z) 列的点,在搜索或输入时一定要注意!

    Code

    #include <bits/stdc++.h>
    using namespace std;
    int a[11][11][11],v[11][11][11];
    struct node{
        int x,y,z;
    }d[1010];//bfs的队列 
    int dx[6]={1,0,0,-1,0,0},dy[6]={0,1,0,0,-1,0},dz[6]={0,0,1,0,0,-1};//坐标移动数组 
    int px[1010],py[1010],pz[1010];//输出(put_out)数组 
    int m,n,p,zx,zy,zz;
    bool bfs()//判断是否能够到达终点 
    {
        int head=1,tail=2;
        while(head<=tail){
            if(d[head].x==zx&&d[head].y==zy&&d[head].z==zz)
                return true;
            for(int i=0;i<=5;i++){
                int tx=d[head].x+dx[i],ty=d[head].y+dy[i],tz=d[head].z+dz[i];
                if(!v[tz][tx][ty]&&a[tz][tx][ty]){//【注意】在这里我的坐标是(z,x,y)! 
                    v[tz][tx][ty]=1;//第z层的第x行第y列的点 
                    d[tail].x=tx;
                    d[tail].y=ty;
                    d[tail].z=tz;
                    tail++;
                }
            }
            head++;
        }
        return false;
    }
    void put_out(int x)
    {
        for(int i=0;i<x;i++)
            printf("(%d,%d,%d)->",px[i],py[i],pz[i]);
        printf("(%d,%d,%d)
    ",px[x],py[x],pz[x]);
        return;
    }
    void dfs(int x,int y,int z,int cnt)
    {
        if(x<1||y<1||z<1||x>n||y>m||z>p) return;//这里x、y、z对应的n、m、p和输入时的顺序有所不同
        if(x==zx&&y==zy&&z==zz){//x指层数,y、z才是横纵坐标哦
            put_out(cnt);
            return;
        }
        for(int i=0;i<6;i++){
            int tx=x+dx[i],ty=y+dy[i],tz=z+dz[i];
            if(a[tz][tx][ty]){
                a[tz][tx][ty]=0;
                cnt++;
                px[cnt]=tx;
                py[cnt]=ty;
                pz[cnt]=tz;
                dfs(tx,ty,tz,cnt);
                cnt--;
                a[tz][tx][ty]=1;
            }
        }
    }
    int main()
    {
        scanf("%d%d%d%d%d%d",&p,&n,&m,&zx,&zy,&zz);
        for(int i=1;i<=p;i++)//【注意!】a(i,j,k)在这里记录的是第i层j行k列的点 
            for(int j=1;j<=n;j++)//如果在这里的输入改为a[j][k][i],上面的搜索中就可以用x,y,z了 
                for(int k=1;k<=m;k++)
                    scanf("%d",&a[i][j][k]);
        d[1].x=d[1].y=d[1].z=1;
        memset(v,0,sizeof(0));
        v[1][1][1]=0;
        if(!bfs()){//如果不能到达直接输出-1 
            printf("-1");
            return 0;
        }
        px[0]=py[0]=pz[0]=1;
        a[1][1][1]=0;
        dfs(1,1,1,0);
        return 0;
    }
    

    说实话是一道很好的搜索题目,同时考察了 (dfs)(bfs)

    LGJ NB!!!(破音)

    最后,完结撒fa~

  • 相关阅读:
    20135223何伟钦—信息安全系统设计基础第十三周学习总结
    20135223何伟钦—信息安全系统设计基础第十二周学习总结
    20135223何伟钦—信息安全系统设计基础第十一周学习总结
    20135223何伟钦—家庭作业汇总
    20135223何伟钦—信息安全系统设计基础第十周学习总结
    20135223何伟钦—第十章家庭作业
    20135223何伟钦—第六章家庭作业
    20135223何伟钦—信息安全系统设计基础第九周学习总结
    20135223/20135234/20135229小组——亚博 Arduino智能小车实践报告
    20135223何伟钦—信息安全系统设计基础期中总结
  • 原文地址:https://www.cnblogs.com/unknown-year/p/13910905.html
Copyright © 2011-2022 走看看