水管工游戏——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("\n"); return 0; }