水管工游戏

来源:互联网 发布:java删除linux文件夹 编辑:程序博客网 时间:2024/04/27 13:23

                                                                                     水管工游戏     

最近小哼又迷上了一个叫做水管工的游戏,游戏的大致规则是这样的,一块矩形土地被划分为N*N的单位正方形,现在这块土地上已经埋设有一些水管,水管将从坐标(1,1)的矩形土地的左上角左部边缘,延伸到坐标为(N,M)的矩形土地的右下角右部边缘,水管只有2种,如下图所示:



每种管道将占据一个单位正方形土地。你现在可以旋转这些管道,使其构成一个管道系统,即创造一条从(1,1)到(N,M)的连通管道。标有树木的方格表示这里没有管道,如下图表示一个5*4的土地中(2,4)处有一个树木:



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


如果通过旋转管道可以使之构成一个连通的管道系统,就输出铺设的路径,否则输出impossible,
例如输入如下数据:
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)

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




思路:


因为只有俩种水管,一种是弯管,一种是直管,弯管有4种状态,直管有2种状态,首先从(1,1)处开始尝试,(1,1)是直管,并且进水口在左边,因此(1,1)处的水管只能使用5号这种方式,如下图



之后达到(1,2),(1,2)是弯管,进水口在左边,因此(1,2)的水管有2种摆放方式,分别是3号和4号,我们先尝试3号这种摆放方式(其实摆放4号是不行的,因为会出界),之后到(2,2),如下图:



(2,2)是直管,并且进水口在上面,因此也只能使用6号这种摆放方式,接下来到(3,2),如下图:



(3,2)是弯管,并且进水口在上面,因此有2种摆放方式,分别是1号和4号,如下图:



这俩种都可以,我们分别取尝试。。。。。。按照上面的方法,直接到(n,m+1)的时候为止,便产生了一种方案:
代码如下:
#include<stdio.h>int a[51][51];int book[51][51];int n,m,flag=0;struct node{int x;int y;}s[100];int top=0;void dfs(int x,int y,int front){int i;if(x==n&&y==m+1){flag=1;for(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(front==1){dfs(x,y+1,1);}if(front==2){dfs(x+1,y,2);}if(front==3){dfs(x,y-1,3);}if(front==4){dfs(x-1,y,4);}}if(a[x][y]>=1&&a[x][y]<=4){if(front==1){dfs(x+1,y,2);dfs(x-1,y,4);}if(front==2){dfs(x,y+1,1);dfs(x,y-1,3);}if(front==3){dfs(x-1,y,4);dfs(x+1,y,2);}if(front==4){dfs(x,y+1,1);dfs(x,y-1,3);}}book[x][y]=0;top--;return ;}int main(){int i,j,num=0;scanf("%d %d",&n,&m);for(i=1;i<=n;i++){for(j=1;j<=m;j++){scanf("%d",&a[i][j]);}}dfs(1,1,1);if(flag==0)   printf("impossible\n");return 0;}







1 0
原创粉丝点击