题面(from luogu)
走迷宫
有一个m*n格的迷宫(表示有m行、n列),其中有可走的也有不可走的,如果用1表示可以走,0表示不可以走,文件读入这mn个数据和起始点、结束点(起始点和结束点都是用两个数据来描述的,分别表示这个点的行号和列号)。现在要你编程找出所有可行的道路,要求所走的路中没有重复的点,走时只能是上下左右四个方向。如果一条路都不可行,则输出相应信息(用-l表示无路)。
优先顺序:左上右下
输入格式:
第一行是两个数 m,n(1<m,n<15),接下来是m行n列由1和0组成的数据,最后两行是起始点和结束点。
输出格式:
所有可行的路径,描述一个点时用(x,y)的形式,除开始点外,其他的都要用“一>”表示方向。
如果没有一条可行的路则输出-1。
样例.in
5 6
1 0 0 1 0 1
1 1 1 1 1 1
0 0 1 1 1 0
1 1 1 1 1 0
1 1 1 0 1 1
1 1
5 6
样例.out
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(2,5)->(3,5)->(3,4)->(3,3)->(4,3)->(4,4)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(2,5)->(3,5)->(3,4)->(4,4)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(2,5)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(3,3)->(4,3)->(4,4)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(4,4)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(3,4)->(2,4)->(2,5)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(3,4)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(3,4)->(4,4)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(4,3)->(4,4)->(3,4)->(2,4)->(2,5)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(4,3)->(4,4)->(3,4)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(4,3)->(4,4)->(4,5)->(5,5)->(5,6)
题目分析
感觉就是这一题:https://www.luogu.org/problemnew/show/P1605 的翻版(不知道为什么难度会上升。。。)
具体的可见这个:https://blog.csdn.net/c_uizrp_dzjopkl/article/details/81813542
大体上面是一样的,但是,有一点是需要注意的:优先顺序:左上右下
我被坑到了。。。。。。。。
代码
#include <bits/stdc++.h>
using namespace std;
int dx[5]={0,0,-1,0,1}; //介值(注意:有优先级的!)
int dy[5]={0,-1,0,1,0};
int a[20][20],ans[10000][3],vis[20][20],n,m,a1,a2,b1,b2,k=1,total=0;
//a是同map数组,ans存的是答案,vis判断那些点去过,k是当前答案长度,total用来判断有没有答案
void write(int c) //自己写的输出函数
{
// cout<<'(',a1<<','<<a2')'<<"->";
for (int i = 1; i <= c; i++)
cout<<'('<<ans[i][1]<<','<<ans[i][2]<<")->";
cout<<'('<<b1<<','<<b2<<')'<<endl;
total++; //方案数++
}
void search(int x,int y) //x,y是当前的位置
{
if (x == b1 && y == b2) //找到目标点了
{
write(k-1); //从k-1个开始输出
return; //回溯
}
else //没找到就继续找
{
for (int i = 1; i <= 4; i++) //四个方向开始搜
if (a[x+dx[i]][y+dy[i]] == 0 || vis[x+dx[i]][y+dy[i]] == 1) continue; //要跳过的条件
else //反之就是可以走
{
ans[k][1] = x; //记录x轴答案
ans[k][2] = y; //y轴答案
k++; //答案的长度+1;
vis[x+dx[i]][y+dy[i]] = 1; //打标记
search(x+dx[i],y+dy[i]); //向前搜
vis[x+dx[i]][y+dy[i]] = 0; //回溯
k--;
}
}
}
int main()
{
memset(a,0,sizeof(a)); //初始化
memset(vis,0,sizeof(vis)); //所有的点都没有走过
cin>>n>>m; //输入
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin>>a[i][j];
cin>>a1>>a2; //起点
cin>>b1>>b2; //终点
vis[a1][a2] = 1; //起点永远要标记!!!
search(a1,a2); //从给出的点开始搜
if (total == 0) cout<<-1; //无解情况的输出
return 0; //完美的结束程序
}
**蒟蒻新星c_uizrp_dzjopkl原创**