175. 电路维修
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 510;
int n, m;
char g[N][N];
int d[N][N];
int bfs() {
memset(d, 0x3f, sizeof(d));
deque<PII> dq;
dq.push_back({0, 0});
d[0][0] = 0;
int dx[4] = {-1, -1, 1, 1}, dy[4] = {-1, 1, 1, -1};
int ix[4] = {-1, -1, 0, 0}, iy[4] = {-1, 0, 0, -1};
char cs[] = "\\/\\/";
while (dq.size()) {
auto t = dq.front();
dq.pop_front();
int x = t.first, y = t.second;
for (int i = 0; i < 4; ++i) {
int a = x + dx[i], b = y + dy[i];
if (a >= 0 && a <= n && b >= 0 && b <= m) {
int w = 0;
int j = x + ix[i], k = y + iy[i];
if (g[j][k] != cs[i])
w = 1;
if (d[a][b] > d[x][y] + w) {
d[a][b] = d[x][y] + w;
if (w)
dq.push_back({a, b});
else
dq.push_front({a, b});
}
}
}
}
if (d[n][m] == 0x3f3f3f3f)
return -1;
else
return d[n][m];
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m);
for (int i = 0; i < n; ++i)
scanf("%s", g[i]);
int t = bfs();
if (t == -1)
puts("NO SOLUTION");
else
printf("%d\n", t);
}
return 0;
}
题解:这个题目就是把网格点看成是一个个结点,斜杠看成是可连接的路径,求从(0,0)出发到达(n,m)点的最短路径,这里要巧妙地开两个数组分别储存结点位置和路径位置,之后开一个双端队列deque,因为这里的路径长度只看做0或者1,所以用双端队列比优先队列要快,如果当前选的路径长度为0,就加到队首,如果长度是1,就加到队尾,这样保证最优。