描述
输入描述:
输出描述:
每组测试数据对应为一行,若 gloria 能从一个位置走到另外一个位置,输出 yes
,否则输出 no
输入
2
5 5
...**
*.**.
.....
.....
*....
1 1 1 1 3
5 5
...**
*.**.
.....
.....
*....
2 1 1 1 3
输出
no
yes
代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <limits.h>
#include <queue>
using namespace std;
struct Node {
int x;
int y;
int direct; // 1,2,3,4 四个方向
int turn; // 已经转弯的次数
Node(int _x, int _y, int _direct, int _turn) {
x = _x;
y = _y;
direct = _direct;
turn = _turn;
}
};
bool operator<(Node lsh, Node rsh) {
return lsh.turn > rsh.turn;
}
char maze[200][200];
int main() {
int t;
scanf("%d", &t);
for (int idx = 0; idx < t; ++idx) {
int m, n;
scanf("%d%d", &m, &n);
// m n 是行和列
for (int i = 0; i < m; ++i) {
scanf("%s", maze[i]);
}
int k, x1, x2, y1, y2;
// k 最多转弯数
scanf("%d%d%d%d%d", &k, &y1, &x1, &y2, &x2);
--x1; // 将编号从1到N 转成下标从0到N-1
--x2;
--y1;
--y2;
int vis[101][101][5];
for (int i = 0; i < 101; ++i) {
for (int j = 0; j < 101; ++j) {
vis[i][j][1] = INT_MAX; //目前按照1方向到达i,j位置所经历的最小转弯次数
vis[i][j][2] = INT_MAX; //目前按照2方向到达i,j位置所经历的最小转弯次数
vis[i][j][3] = INT_MAX; //目前按照3方向到达i,j位置所经历的最小转弯次数
vis[i][j][4] = INT_MAX; //目前按照4方向到达i,j位置所经历的最小转弯次数
}
}
priority_queue<Node> tovisit; // 使用优先队列保存待访问的邻居结点
Node root(x1, y1, 0, 0); // 0 表示当前没有任何方向
tovisit.push(root);
bool isfind = false;
while (!tovisit.empty()) {
// 当前结点
Node cur = tovisit.top();
int x = cur.x, y = cur.y;
tovisit.pop();
if (cur.x == x2 && cur.y == y2) {
isfind = true;
break;
}
// 假设下一步走1方向
int nextTurn = (cur.direct == 1) ? cur.turn : cur.turn + 1;
// 假设下一个位置在范围内,且消耗转向次数更少,则入队
if (nextTurn <= k + 1 && x + 1 < m && maze[x + 1][y] != '*' && vis[x + 1][y][1] > nextTurn) {
Node next(x + 1, y, 1, nextTurn);
tovisit.push(next);
vis[x + 1][y][1] = nextTurn;
}
// 假设下一步走2方向
nextTurn = (cur.direct == 2) ? cur.turn : cur.turn + 1;
if (nextTurn <= k + 1 && x - 1 >= 0 && maze[x - 1][y] != '*' && vis[x - 1][y][2] > nextTurn) {
Node next(x - 1, y, 2, nextTurn);
tovisit.push(next);
vis[x - 1][y][2] = nextTurn;
}
nextTurn = (cur.direct == 3) ? cur.turn : cur.turn + 1;
if (nextTurn <= k + 1 && y + 1 < n && maze[x][y + 1] != '*' && vis[x][y + 1][3] > nextTurn) {
Node next(x, y + 1, 3, nextTurn);
tovisit.push(next);
vis[x][y + 1][3] = nextTurn;
}
nextTurn = (cur.direct == 4) ? cur.turn : cur.turn + 1;
if (nextTurn <= k + 1 && y - 1 >= 0 && maze[x][y - 1] != '*' && vis[x][y - 1][4] > nextTurn) {
Node next(x, y - 1, 4, nextTurn);
tovisit.push(next);
vis[x][y - 1][4] = nextTurn;
}
}
if (isfind) {
printf("yes\n");
// printf("%d\n", dis[x2][y2]);
}
else {
printf("no\n");
}
}
return 0;
}