链接:https://ac.nowcoder.com/acm/problem/15434
来源:牛客网
题目描述
给你一个n*m的迷宫,这个迷宫中有以下几个标识:
s代表起点
t代表终点
x代表障碍物
.代表空地
现在你们涵哥想知道能不能从起点走到终点不碰到障碍物(只能上下左右进行移动,并且不能移动到已经移动过的点)。
输入描述:
输入第一行一个整数T(1<=T<=10)
接下来有T组测试数据,对于每一组测试数据,第一行输入2个数n和m(1<=n,m<=500)
接下来n行,每行m个字符代表这个迷宫,每个字符都是上面4个中的一种
数据保证只有一个起点和一个终点
输出描述:
对于每一组测试数据,如果可以的话输出YES,不可以的话输出NO
示例1
输入
1 3 5 s...x x...x ...tx
输出
YES
参考代码(DFS)
#include<iostream> #include<string.h> using namespace std; int n,p,q,beginX,beginY,endX,endY;//beginX,beginY:初始坐标 endX,endY:结束坐标 char map[505][505]; bool book[505][505],flag; int NEXT[4][2] = { {-1,0},{0,1},{1,0},{0,-1} };//方向数组 void dfs(int x, int y) { if (x==endX&&y==endY) { flag = true; //cout << "hahha" << endl; return; } for (int i = 0; i <= 3; i++) { int tx = x + NEXT[i][0]; int ty = y + NEXT[i][1]; if (tx < 1 || tx > p || ty <1 || ty>q) { //cout << "越界" << endl; continue; } if ((map[tx][ty] == '.' && book[tx][ty] == false)||(map[tx][ty]=='t'&& book[tx][ty] == false)) { book[tx][ty] = true; cout << "进入dfs" << ":" << tx<<" " << ty << endl; dfs(tx, ty); cout << "出来dfs" << ":" << tx << " " << ty << endl; //book[tx][ty] = false; } if (flag == true) { //cout << "haha" << endl; return; } } } int main() { cin >> n; while (n--) { flag = false; memset(map, ' ',sizeof(map)); memset(book, false, sizeof(book)); cin >> p >> q; for (int i = 1; i <= p; i++) { for (int j = 1; j <= q; j++) { cin >> map[i][j]; if (map[i][j] == 's') { beginX = i; beginY = j; } if (map[i][j] == 't') { endX = i; endY = j; } } } book[beginX][beginY] = true; dfs(beginX, beginY); if (flag) { cout << "YES" << endl; } else { cout << "NO" << endl; } } return 0; }
运行结果
这个题从早上搞到下午四点多,心想要是这个简单的DFS都搞不定,那之后的也就都别学了.不过还是搞出来了,还是在走路的时候知道哪里错了,挺激动的.对于自己算法之路往后走可能很难,但我相信我还是可以把这条路走下去的.
另外调试是个好东西,可以看看自己的预期与运行是否一致也可以更好的帮助我们理解程序.
在这条路上也遇到了很多志同道合的人无论是不厌其烦给我修改代码的学长,还是算法群里那些热情的伙伴,渐渐发现其实学习算法挺爽的,尤其是当你AC一道题的时候.
总之,继续加油,希望自己的算法之路越走越远!
收获
DFS如果求得只是A点到B点是否能够到达(只是求是否存在建议使用BFS),那么便不用进行回溯.如果要求最多有几条路径,那么需要回溯.
BFS较适合解决A点到B点能够到达的最优解.
字符数组默认初始化为空格,ASCII为32
本题中注意tx和ty只能是局部变量,不能搞成全局.不然到时候递归回去时就出问题了.