DFS-水管工游戏


今天来复习一下如何用DFS找到能使首尾连接的通道,并显示出来。

题目描述

一块矩形土地被分为N*M的单位正方形,现在这块土地上已经埋设有一些水管,水管将从坐标为(1,1)的矩形土地的左上角坐标边缘,延伸到坐标为(N,M)的矩形土地的右下角右部边缘。水管有两种,弯的和直的。
每种管道将占据一个单位正方形土地。你现在可以旋转这些管道,使其构成一个管道系统,即创造一条从(1,1)到(N,M)的连通管道。标有数目的方格表示这里没有管道。

输入

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

输出

如果通过旋转管道可以使之构成一个连通的管道系统,就输出铺设的路径,否则输出impossible。

输入样例1

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) (1,2) (2,2) (3,2) (3,3) (3,4) (4,4) (5,4)

输入样例2

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

输出样例2

impossible

AC代码

#include<bits/stdc++.h>
using namespace std;
int book[51][51],a[51][51];
int next[5][2]={
    
    {
    
    0,0},{
    
    0,1},{
    
    1,0},{
    
    0,-1},{
    
    -1,0}};
int top;
int n,m,flag;  //flag 用来标记
struct note{
    
    
	int x,y;
}s[2501];  //用栈来存储路径

void dfs(int x,int y,int t)
{
    
    
	int tx,ty;
	if(x==n&&y==m+1){
    
      //如果有路径,标记flag,并输出路径
		flag=1;
		for(int i=1;i<=top;i++)
		printf("(%d,%d)",s[i].x,s[i].y);
		return;
	}
	
	if(x<1||x>n||y<1||y>m) return;  //防止越界
	
	if(book[x][y]==1) return ;   //如果已经走过
	
	book[x][y]=1;   //走过的路径标记下
	top++;   //入栈操作
	s[top].x=x;
	s[top].y=y;
	
	if(a[x][y]>=5&&a[x][y]<=6){
    
      //直管  有横竖 两种摆放方式
		if(t==1){
    
       //t=1说明管口在左侧
			dfs(x,y+1,1);   //管口在左侧,另一边就在右侧,就通过了右边的方格,所以y+1 ,  此时对右侧的方格而言,管口还是在左侧,所以是1
		}
		if(t==2){
    
       //t=2说明管口在上侧
			dfs(x+1,y,2);  //同理,
		}
		if(t==3){
    
       //t=3说明管口在右侧
			dfs(x,y-1,3);
		}
		if(t==4){
    
       //t=4说明管口在下侧
			dfs(x-1,y,4);
		}
	}
	
	if(a[x][y]>=1&&a[x][y]<=4){
    
    
		if(t==1){
    
    
			dfs(x-1,y,4);
			dfs(x+1,y,2);
		}
		if(t==2){
    
    
			dfs(x,y-1,3);
			dfs(x,y+1,1);
		}
		if(t==3){
    
    
			dfs(x-1,y,4);
			dfs(x+1,y,2);
		}
		if(t==4){
    
    
			dfs(x,y-1,3);
			dfs(x,y+1,1);
		}
	}
	
	book[x][y]=0;  //回溯
	top--;    
}
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) printf("impossible");  //如果flag没有被标记,说明没有路径,输出impossible
	
	return 0;
} 

好啦,解题完毕!!!!

猜你喜欢

转载自blog.csdn.net/qq_45735298/article/details/108146401