一、规则
最近小哼又迷上一个叫做水管工的游戏。游戏的大致规则是这样的。一块矩形土地被分为N * M的单位正方形,现在这块土地上已经埋设有一些水管,水管将从坐标为(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个整数,表示地图中的每一小格。其中О表示树木,1~6分别表示管道的六种不同的摆放方式,如下图。
因为只有两种水管,一种是弯管一种是直管。弯管有4种状态,直管有2种状态。首先从(1,1)处开始尝试。(1,1)是直管,并且进水口在左边,因此(1,1)处的水管只能使用5号这种摆放方式,如下图。
之后达到(1.2)。(1.2)是弯管,进水口在左边,因此(1,2)的水管有2种摆放方式,分别是3号和4号。我们先尝试3号这种摆放方法〈其实摆放4号是不行的,因为会出界),之后到达(2,2),如下图。
#include<iostream>
using namespace std;
struct node{
int x;
int y;
};//用来记录经过点的坐标
static int a[15][15];
int book[15][15] = {0};
node root[15];//记录路径
int size;
static int N, M;
static int flag = 0;
static void dfs(int x, int y, int front){
if (x == N - 1 && y == M){//这里的y值要注意,要超出图边界,水管要出水,出图
flag = 1;
for (int i = 0; i<size; ++i)
cout <<"("<< root[i].x +1<<","<< root[i].y+1 <<")"<< " ";
return;
}
if (x<0 || x >= N || y<0 || y >= M) return;//超过图边界return
if (book[x][y]==1) return;//标记过return
book[x][y] = 1;//标记
root[size].x = x;//把经过的点放入路径栈
root[size++].y = y;
//水管口 左1 上2 右3 下4
if (a[x][y] >= 5 && a[x][y] <= 6){//直的水管两种放置方式横放竖放
if (front == 1)//水管口在左边
dfs(x, y + 1, 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, 2);
dfs(x - 1, y, 4);
}
if (front == 4){
dfs(x, y + 1, 1);
dfs(x, y - 1, 3);
}
}
book[x][y] = 0;
if (size > 0) size--;
return;
}
int main(int argc, char** argv)
{
int test_case;
int T;
/*
The freopen function below opens input.txt in read only mode and
sets your standard input to work with the opened file.
When you test your code with the sample data, you can use the function
below to read in from the sample data file instead of the standard input.
So. you can uncomment the following line for your local test. But you
have to comment the following line when you submit for your scores.
*/
//freopen("input.txt", "r", stdin);
cin >> T;
/*
Read each test case from standard input.
*/
for (test_case = 1; test_case <= T; ++test_case)
{
cin >> N >> M;
for (int i = 0; i < N; i++){
for (int j = 0; j < M; j++){
a[i][j] = 0;
book[i][j] = 0;
}
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
cin >> a[i][j];
dfs(0, 0, 1);
if (flag == 0)
cout << "NO";
else
cout << "YES";
}
return 0;//Your program should return 0 on normal termination.
}
}