欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

水管工游戏

程序员文章站 2022-07-24 13:07:17
原创 游戏的大致规则是这样的:一块矩形土地被分为N*M的单位正方形,现在这块土地上已经埋设有一些水管,水管将从坐标 为(0,0)的矩形土地的左上角左部边缘,延伸到坐标为(N-1,M-1)的矩形土地的右下角右部边缘。水管只有2种,如下 所示。 每种管道将占据一个单位正方形土地。现在可以旋转这些管道,使 ......

原创

游戏的大致规则是这样的:一块矩形土地被分为N*M的单位正方形,现在这块土地上已经埋设有一些水管,水管将从坐标

为(0,0)的矩形土地的左上角左部边缘,延伸到坐标为(N-1,M-1)的矩形土地的右下角右部边缘。水管只有2种,如下

所示。

水管工游戏

每种管道将占据一个单位正方形土地。现在可以旋转这些管道,使其构成一个管道系统,即创造一条从(0,0)到(N-1,M-1)

的连通管道。标有树木的方格表示这里没有管道。如下图表示一个5*4的土地中(2,4)处有一个树木。

水管工游戏

我们可以旋转其中的一些管道,使之构成一个连通的管道系统,如下图:

水管工游戏

输入的第一行为两个整数N和M,接下来的N行,每行有M个整数,表示地图中的每一小格。其中0表示树木,

1~6分别表示管道的六种不同的摆放方式,如下图:

水管工游戏

解题思路:

  解题用深搜(一笔画问题),但是此题的深搜方向由于进水口的方向限制,最多只能有两种情况,所以

不必要设置方向数组了;由于水管只有两种状态,弯管和直管,所以只要枚举这两种状态,在这两种状态的

基础上再枚举水管的四个方向,就能分别确定接下来水通往哪个格子,再继续枚举下去即可。

import java.util.*;

public class 水管工游戏 {
    
    static int count=0;
    static int flag=0;
    static int n;
    static int m;
    static int maze[][];
    static int book[][];
    static ArrayList listx=new ArrayList();
    static ArrayList listy=new ArrayList();
    
    static void dfs(int x,int y,char way) {    //way代表入水口
        if(x==n-1 && y==m) {    //成功判断
            flag=1;
            return;
        }
        if(x<0 || x>n-1 || y<0 || y>m-1) {    //越界判断
            return;
        }
        if(maze[x][y]==0 || book[x][y]==1) {    //树木与访问判断
            return;
        }
        book[x][y]=1;
        listx.add(x);
        listy.add(y);
        count++;
        if(maze[x][y]==5 || maze[x][y]==6) {    //直管
            if(way=='l') {    //左
                dfs(x,y+1,'l');
            }
            if(way=='r') {    //右
                dfs(x,y-1,'r');
            }
            if(way=='u') {    //上
                dfs(x+1,y,'u');
            }
            if(way=='d') {    //下
                dfs(x-1,y,'d');
            }
        }
        if(maze[x][y]>=1 && maze[x][y]<=4){    //弯管
            if(way=='l') {    //左
                dfs(x-1,y,'d');
                dfs(x+1,y,'u');
            }
            if(way=='r') {    //右
                dfs(x-1,y,'d');
                dfs(x+1,y,'u');
            }
            if(way=='u') {    //上
                dfs(x,y-1,'r');
                dfs(x,y+1,'l');
            }
            if(way=='d') {    //下
                dfs(x,y-1,'r');
                dfs(x,y+1,'l');
            }
        }
        if(flag==1) {
            return;
        }
        book[x][y]=0;    //回溯
        listx.remove(count-1);
        listy.remove(count-1);
        count--;
        return;
    }

    public static void main(String[] args) {
        Scanner reader=new Scanner(System.in);
        n=reader.nextInt();
        m=reader.nextInt();
        maze=new int[n][m];
        book=new int[n][m];
        for(int i=0;i<n;i++) {
            for(int j=0;j<m;j++) {
                maze[i][j]=reader.nextInt();
                book[i][j]=0;
            }
        }
        dfs(0,0,'l');
        if(flag==1) {
            System.out.println("YES");
        }
        else {
            System.out.println("NO");
        }
        System.out.print("路径为:");
        for(int i=0;i<count;i++) {
            System.out.print("("+listx.get(i)+","+listy.get(i)+")"+" ");
        }
    }
}

测试用例:

输入:

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

输出:
YES
路径为:(0,0) (0,1) (1,1) (2,1) (2,2) (2,3) (3,3) (4,3)

11:05:05

2018-07-22