• 水管工游戏——dfs


    • 问题描述:

    水管工游戏是指如下图中的矩阵中,一共有两种管道,一个是直的,一个是弯的,所有管道都可以自由旋转,最终就是要连通入水口可出水口。其中的树为障碍物。

            

    方案:

    输入格式:输入的第一行为两个整数N和 M(都不超过10),接下来的N行,每行有M个整数,表示地图中的每一小格。其中0表示树木,1~6分别表示管道的六种不同的摆放方式

    输入:

    5 4
    5 3 5 3
    1 5 3 0
    2 3 5 1
    6 1 1 5
    1 5 5 4

    输出:

    (1,1) (1,2) (2,2) (3,2) (3,3) (3,4) (4,4) (5,4)

    • 算法思路:

    本题使用的是深度优先搜索算法,先标识入水口方向,在每次探索新管道的时候上根据入水口方向进行扩展,然后根据管道的类型来判断下一个节点的入水口方向。水管入口:1代表左,2代表右,3代表上,4代表下。

    • 代码:

    #include<cstdio>
    #include<iostream>
    #define INF 10000000
    using namespace std;
    int n,m,flag=0;
    int a[10][10],b[10][10];
    int next[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
    struct node
    {
        int x,y;
    }s[100];
    int top=0;
    void dfs(int x,int y,int r)
    {
    
        if(x==n&&y==m+1)//走到出口
        {
            flag=1;
            for(int i=1;i<=top;i++)
                printf("(%d,%d)",s[i].x,s[i].y);
            return ;
        }
        if(x<1||y<1||x>n||y>m)return ;
        if(b[x][y]==1)//如果这个点已在路径中
            return ;
        b[x][y]=1;//标记
        top++;
        s[top].x=x;
        s[top].y=y;
        //直水管的情况
        if(a[x][y]==5||a[x][y]==6)
        {
            if(r==1)//入口在左
            {
                dfs(x,y+1,1);
            }
            else if(r==2)//入口在右
            {
                dfs(x,y-1,2);
            }
            else if(r==3)//入口在上
            {
                dfs(x+1,y,3);
            }
            else//入口在下
            {
                dfs(x-1,y,4);
            }
        }
        //弯水管的情况
        if(a[x][y]>=1&&a[x][y]<=4)
        {
            if(r==1)
            {
                dfs(x+1,y,3);
                dfs(x-1,y,4);
            }
            else if(r==2)
            {
                dfs(x-1,y,4);
                dfs(x+1,y,3);
            }
            else if(r==3)
            {
                dfs(x,y+1,1);
                dfs(x,y-1,2);
            }
            else
            {
                dfs(x,y+1,1);
                dfs(x,y-1,2);
            }
        }
        b[x][y]=0;//尝试过不能用的点要取消标记并且出栈
        top--;
        return ;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&a[i][j]);
            }
        }
        dfs(1,1,1);
        if(flag==0)
            printf("impossible");
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    【转】C#中的虚方法
    【转】ASP.NET 2.0中Page事件的执行顺序
    OWC ChartSpace控件的使用
    Ext对基本类型的扩展
    OWC PivotTable的使用方法
    .net中线程同步的典型场景和问题(1)
    python中使用汉字
    如何取消后台线程的执行
    yaffs2根文件系统的构建过程
    Fuck self.delegate = self
  • 原文地址:https://www.cnblogs.com/boboyuzz/p/10428089.html
Copyright © 2020-2023  润新知