标签:
/*
让我们一起装水管吧!
问题描述:
一块矩形土地被分为N*M的单位正方形,现在土地上已经设有一些水管,
水管将从坐标为(1,1)的矩形土地左上角左部边缘,延伸到坐标为(N,M)的
矩形土地的右下角右部边缘,(即左上角的单位正方形的左边为进水口,右下角的单位正方形的右边为出水口)。水管只有两种 L型和I型水管。每种管道将占据一个单位正方形土地。你现在可以旋转这些管道,使其构成一个管道系统,即创造出一条从
(1,1)到(N*M)的连通管道。注意,这块矩形土地内可能会有树木阻挡你放置管道。
L型水管有4种放置方法, I型水管有两种放置方法.
分别表示如下:
^ —> <— ^ ^
| | | | | < —> 树木用0表示
—> v v <— v
1 2 3 4 5 6
输入描述 InputDescription
第一行输入两个整数N,M (0<N,M<=50),用空格分隔开。表示将土地划分为N*M个单 位正方形。
剩下N行,每行有M个数,行内的数用空格隔开,行间要换行。表示各个单位
正方形土地的情况(水管or树木)。
输出描述 OutDescription
输出水管的连通方式,格式为(i,j) (0<i<=50,0<j<=50)
若无法形成一个连通系统则输出 impossible 。
样例输入 SampleInput
5 4
5 3 5 3
1 5 3 0
2 3 5 1
6 1 1 5
1 5 5 4
样例输出 SampleOutput
(1,1) (1,2) (2,2) (3,2) (3,3) (3,4) (4,4) (5,4)
*/
#include <iostream>
using namespace std;
int map[51][51]; // map 地图
bool mark[51][51]; // 标记
int n,m,top; // n行 m列 top栈顶
bool flag; // 判断是否存在可连通的系统
typedef struct // 用于储存结果
{
int x; // 横坐标
int y; // 纵坐标
} no, nodeList[2501]; // 栈nodeList
nodeList node;
// 广搜
void DFS(int x,int y,int front) // front为进水口 1,2,3,4分别表示左上右下
{
if(x==n && y==m+1) // 判断是否找到出水口
{
flag = true; // 标记连通系统已完成
for(int i=1;i<=top;i++) // 输出各管道路径
cout<<"("<<node[i].x<<","<<node[i].y<<")"<<ends;
return;
}
if(x<1 || x>n || y<1 || y>m) // 判断坐标是否越界
return;
if(mark[x][y]) // 判断该水管是否已被使用
return;
mark[x][y] = true; // 将该水管标记为已使用
node[++top].x = x; // 将当前水管坐标存入栈
node[top].y = y;
if(map[x][y]>=1 && map[x][y]<=4) // L型水管有4种摆放方式(1~4)
{
switch(front)
{
case 1: // 当进水口在左边 (L型水管对应的摆放方式有3、4)
DFS(x+1,y,2); // 方式3:向下搜,向下后进水口改为上
DFS(x-1,y,4); // 方式4:向上搜,向上后进水口改为下
break;
case 2: // 当进水口在上边 (L型水管对应的摆放方式有1、4)
DFS(x,y+1,1); // 方式1:向右搜,向右后进水口改为左
DFS(x,y-1,3); // 方式4:向左搜,向左后进水口改为右
break;
case 3: // 当进水口在右边 (L型水管对应的摆放方式有1、2)
DFS(x-1,y,4); // 方式1:向上搜,向上后进水口改为下
DFS(x+1,y,2); // 方式2:向下搜,向下后进水口改为上
break;
case 4: // 当进水口在下边 (L型水管对应的摆放方式有2、3)
DFS(x,y+1,1); // 方式2:向右搜,向右后进水口改为左
DFS(x,y-1,3); // 方式3:向左搜,向左后进水口改为右
break;
}
}
else if(map[x][y]>=5 && map[x][y]<=6) // I型水管有2种摆放方式(5~6)
{
switch(front)
{
case 1: // 当进水口在左边 (I型水管对应的摆放方式有5)
DFS(x,y+1,1); // 方式5:向右搜,向右后进水口仍为左
break;
case 2: // 当进水口在上边 (I型水管对应的摆放方式有6)
DFS(x+1,y,2); // 方式6:向下搜,向下后进水口仍为上
break;
case 3: // 当进水口在右边 (I型水管对应的摆放方式有5)
DFS(x,y-1,3); // 方式5:向左搜,向左后进水口仍为右
break;
case 4: // 当进水口在下边 (I型水管对应的摆放方式有6)
DFS(x,y+1,4); // 方式6:向上搜,向上后进水口仍为上
break;
}
}
mark[x][y] = 0; // 该点尝试过后,取消标记
return;
}
int main()
{
int i,j;
cin>>n>>m; // 输入表示 有n*m个单位正方形
if(n<=0 || n>50) return -1;
if(m<=0 || m>50) return -1;
for(i=1;i<=n;i++) // 读入地图
for(j=1;j<=m;j++)
cin>>map[i][j];
top = 0; // 栈顶初始化为0
DFS(1,1,1); // 从(1,1)开始搜,定义一开始的进水口在左边
if(!flag) // 当前水管的设置不可能装成一个连通系统时输出 impossible
cout<<"impossible"<<endl;
return 0;
}
标签:
原文地址:http://blog.csdn.net/madbam_boo/article/details/51362471