abc 246 e 题解
abc 246 e
题意#
有一个
棋盘用
-
如果
.
,则格子 是空的。 -
否则,格子
有障碍。
一开始格子
请你求出棋子从 -1
。
思路#
很明显,这题求最短路,是广搜。
但是,这个移动方式很让人头疼,每次到底挪动几次呢?
如果每次都去枚举移动的步数,时间复杂度又变成了
那么,我们应该怎么解决呢?
其实,每次只用走一步,但是,我们每次需要记录是往哪个方向走的。
如果当前走的方向和转移来的那个状态的转移方向是不同的,就需要多一次操作,否则,就还是这次操作。
因为每次转移有可能增加操作次数,有可能不增加,所以是 0-1 BFS,用双端队列维护。
#include <bits/stdc++.h>
using namespace std;
const int N = 1510;
const int dx[] = {1, 1, -1, -1};
const int dy[] = {1, -1, 1, -1};
int n, sx, sy, fx, fy, d[N][N][4];
char c[N][N];
struct Node {
int x, y, dir; // dir 表示方向
};
deque<Node> que;
void Record(int x, int y, int dis, int dir, int nowd) {
if (x < 1 || x > n || y < 1 || y > n || c[x][y] == '#' || d[x][y][nowd] <= dis + (nowd != dir)) {
return ;
}
d[x][y][nowd] = dis;
if (nowd == dir) {
que.push_front({x, y, nowd});
} else {
d[x][y][nowd]++;
que.push_back({x, y, nowd});
}
}
void bfs() {
for (Record(sx, sy, 0, 4, 4); !que.empty(); ) {
Node u = que.front();
que.pop_front();
for (int i = 0; i < 4; i++) { // 转移
Record(u.x + dx[i], u.y + dy[i], d[u.x][u.y][u.dir], u.dir, i);
}
}
}
int main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> sx >> sy >> fx >> fy;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> c[i][j];
d[i][j][0] = d[i][j][1] = d[i][j][2] = d[i][j][3] = 1e9; // 初始化
}
}
bfs();
int ans = 1e9;
for (int i = 0; i < 4; i++) {
if (d[fx][fy][i] != 1e9) {
ans = min(ans, d[fx][fy][i]);
}
}
cout << (ans == 1e9 ? -1 : ans);
return 0;
}
作者:cn
出处:https://www.cnblogs.com/chengning0909/p/18422866
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
2023-09-20 线性代数