[AcWing 175] 电路维修
双端队列 BFS
点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 500 + 10;
const int INF = 0x3f3f3f3f;
#define x first
#define y second
int n, m;
char g[N][N];
int d[N][N];
bool st[N][N];
string cs = "\\//\\";
int dx[] = {-1, -1, 1, 1}, dy[] = {-1, 1, -1, 1};
int ix[] = {-1, -1, 0, 0}, iy[] = {-1, 0, -1, 0};
int bfs()
{
memset(d, 0x3f, sizeof d);
memset(st, false, sizeof st);
deque<pair<int,int>> q;
q.push_back({0, 0});
d[0][0] = 0;
while (q.size()) {
auto t = q.front();
q.pop_front();
if (st[t.x][t.y])
continue;
st[t.x][t.y] = true;
for (int i = 0; i < 4; i ++) {
int a = t.x + dx[i], b = t.y + dy[i];
if (a < 0 || a > n || b < 0 || b > m)
continue;
int ca = t.x + ix[i], cb = t.y + iy[i];
int w = g[ca][cb] != cs[i];
int dist = d[t.x][t.y] + w;
if (dist < d[a][b]) {
d[a][b] = dist;
if (w == 1)
q.push_back({a, b});
else
q.push_front({a, b});
}
}
}
return d[n][m];
}
void solve()
{
cin >> n >> m;
for (int i = 0; i < n; i ++)
for (int j = 0; j < m; j ++)
cin >> g[i][j];
int t = bfs();
if (t == INF)
cout << "NO SOLUTION" << endl;
else
cout << t << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T --) {
solve();
}
// solve();
return 0;
}
- 对于一个位置的字符,有两种状态,右下倾斜和左下倾斜,如果该位置的倾斜方向和输入相同,说明不需要旋转,权值记为 ,否则说明需要旋转,权值记为 ,所有权值为 的点都放到双端队列的头部,权值为 的点都放到双端队列的尾部
- 区分两类坐标,第一类坐标对应的是网格上的点,第二类坐标对应的是输入的字符,对于一个输入的字符,实际上对应了四个网格上的点,对于第一类坐标,能到的点为 ,对于第二类坐标,需要把第一类坐标映射到输入字符坐标上,对于一个网格交点 ,能够映射到的坐标为 ,对应的倾斜方向分别为 右下,左下,左下,右下
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!