一块矩形土地被分成 N*M 的单位正方形,现在这块土地已经埋有一些水管,水管将从坐标为 (1,1)的红矩形土地的左上角
左部边缘,延伸到坐标为(N,M)的矩形土地的右下角右部边缘。水管只有两种,弯管或者直管;
弯管表示为1到4,直管表示为5,6,树木为0;
请编写程序判断该地图是否能得到合理的水管路线;如果能,打印出路径;如果不能,输出impossible。
分析:既然,弯管与直管可以通过变换摆放方式来调整方向,那么我们必定要将(x,y)的进水口方向找到。
不妨设左,上,右,下的方向分别为 1,2,3,4;
/**
一块矩形土地被分成 N*M 的单位正方形,现在这块土地已经埋有一些水管,水管将从坐标为 (1,1)的红矩形土地的左上角
左部边缘,延伸到坐标为(N,M)的矩形土地的右下角右部边缘。水管只有两种,弯管或者直管;
弯管表示为1到4,直管表示为5,6,树木为0;
请编写程序判断该地图是否能得到合理的水管路线;如果能,打印出路径;如果不能,输出impossible。
分析:既然,弯管与直管可以通过变换摆放方式来调整方向,那么我们必定要将(x,y)的进水口方向找到。
不妨设左,上,右,下的方向分别为 1,2,3,4;
*/
/**
data:
5 4
5 3 5 3
1 5 3 0
2 3 5 1
6 1 1 5
1 5 5 4
*/
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 510;
int e[maxn][maxn];
bool hs[maxn][maxn];
int n,m;
int flag = 0;
typedef pair<int,int> PII;
queue<PII> q;
stack<PII> s;
PII stk[maxn];
int top = 0;
void dfs(int x,int y,int fron)
{
if(x == n && y == m+1)
{
flag = 1;
///错误路径,路径应该用栈来存储,用队列来存储的话,每次删除应该是队尾元素,
///但是队列就会删除队头元素(因为队列是先进先出,每次都是把先进去的元素给删除了
while(q.size())
{
PII t = q.front();
q.pop();
cout << t.first << ' ' << t.second << endl;
}
///用栈存储正确路径
puts("--------------");
for(int i=1;i<=top;++i)
cout << stk[i].first << ' ' << stk[i].second << endl;
///STL实现的容器栈只能逆序输出;
puts("************");
while(s.size())
{
PII t = s.top();
s.pop();
cout << t.first << ' ' << t.second << endl;
}
return ;
}
if(x<1 || x>n || y<1 || y>m)
return;
if(hs[x][y])
return;
hs[x][y] = 1;
q.push({x,y});
stk[++top] = {x,y};
s.push({x,y});
if(e[x][y] >= 5 && e[x][y] <= 6) ///直管
{
if(fron == 1)
dfs(x,y+1,1);
else if(fron == 2)
dfs(x+1,y,2);
else if(fron == 3)
dfs(x,y-1,3);
else
dfs(x-1,y,4);
}
else if(e[x][y] >=1 && e[x][y] <= 4) ///弯管
{
if(fron == 1)
{
dfs(x-1,y,4);
dfs(x+1,y,2);
}
else if(fron == 2)
{
dfs(x,y-1,3);
dfs(x,y+1,1);
}
else if(fron == 3)
{
dfs(x-1,y,4);
dfs(x+1,y,2);
}
else
{
dfs(x,y-1,3);
dfs(x,y+1,1);
}
}
hs[x][y] = 0; ///回溯
if(q.size())
q.pop();
-- top; ///将(x,y)出栈
s.pop();
}
int main()
{
cin >> n >> m;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
cin >> e[i][j];
dfs(1,1,1);
if(flag == 0)
puts("impossible");
return 0;
}