算法——广度优先搜索——跨步迷宫
原题链接
思路:找出最短路径,然后判断是否存在连续三个点是横纵坐标相等的,如果有就步数减1
但是有两个样例过不了
错误原因:在错误的测试案例中,最短路径可能有多条,而我刚好选了一条比较曲折的,不能一下子走两步
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<vector<int>> arr(n + 2, vector<int>(m + 2, -1));
vector<vector<int>> state(n + 2, vector<int>(m + 2, 0));
vector<vector<pair<int, int>>> lastNode(n + 2, vector<pair<int, int>>(m + 2, {0, 0}));
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
int num;
cin >> num;
arr[i][j] = num;
}
}
int step = 0;
queue<pair<int, int>> p, c;
bool isFind = false;
p.emplace(1, 1);
while (!p.empty()) {
while (!p.empty()) {
auto cur = p.front();
if (cur.first == n && cur.second == m) {
isFind = true;
break;
}
p.pop();
if (arr[cur.first - 1][cur.second] == 0 && state[cur.first - 1][cur.second] == 0) {
c.emplace(cur.first - 1, cur.second);
state[cur.first - 1][cur.second] = 1;
lastNode[cur.first - 1][cur.second] = {cur.first, cur.second};
}
if (arr[cur.first + 1][cur.second] == 0 && state[cur.first + 1][cur.second] == 0) {
c.emplace(cur.first + 1, cur.second);
state[cur.first + 1][cur.second] = 1;
lastNode[cur.first + 1][cur.second] = {cur.first, cur.second};
}
if (arr[cur.first][cur.second - 1] == 0 && state[cur.first][cur.second - 1] == 0) {
c.emplace(cur.first, cur.second - 1);
state[cur.first][cur.second - 1] = 1;
lastNode[cur.first][cur.second - 1] = {cur.first, cur.second};
}
if (arr[cur.first][cur.second + 1] == 0 && state[cur.first][cur.second + 1] == 0) {
c.emplace(cur.first, cur.second + 1);
state[cur.first][cur.second + 1] = 1;
lastNode[cur.first][cur.second + 1] = {cur.first, cur.second};
}
}
if (isFind) break;
step++;
p = c;
while (!c.empty()) c.pop();
}
vector<pair<int, int>> result;
if (!isFind) {
cout << -1 << endl;
return 0;
} else {
int i = n, j = m;
while (i != 1 || j != 1) {
result.emplace_back(i, j);
auto post = lastNode[i][j];
i = post.first;
j = post.second;
}
}
// cout << "1 1" << endl;
// for (int i = result.size() - 1; i >= 0; --i) {
// auto cur = result[i];
// cout << cur.first << " " << cur.second << endl;
// }
result.emplace_back(1, 1);
int count = result.size() - 1; // 经过多少个点,减去1 就是单步走的最短路径
for (int i = result.size() - 1; i >= 2; --i) {
if (result[i].first == result[i - 1].first && result[i].first == result[i - 2].first) {
count--;
i = i - 1; // 循环结束会减一 所以这里只要减1 一共减2
} else if (result[i].second == result[i - 1].second && result[i].second == result[i - 2].second) {
count--;
i = i - 1;
}
}
cout << count << endl;
return 0;
}