9月7号 第二题速战速决
虽然g了,但还是写出了,差一点啊,难过。
#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <string>
using namespace std;
vector<vector<bool>> visited;
int min_time = INT32_MAX;
vector<pair<int, int>> off_set {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
bool ischange(vector<vector<char>> &streets, int r1, int c1, int r2, int c2, int op) {
//op == 1 遂平
//op == 0 竖直
if (op == -1)
false;
if (op == 0 && r1 == r2)
return true;
if (op == 1 && c1 == c2)
return true;
return false;
}
void dfs(vector<vector<char>> &streets, int row, int colum, int time, int op) {
cout << time << endl;
if (streets[row][colum] == 'E') {
min_time = min(min_time, time);
return ;
}
for (auto &off : off_set) {
int r = row + off.first;
int c = colum + off.second;
if (r < 0 || r >= streets.size() || c < 0 || c >= streets[0].size() ) {
continue;
}
if (visited[r][c])
continue;
if (streets[r][c] == 'X')
continue;
visited[r][c] = true;
bool changed = ischange(streets, row, colum, r, c, op);
int new_op;
if (changed && op == 1)
new_op = 0;
else if (changed && op == 0)
new_op = 1;
else if (op == -1 && r > 1)
new_op = 0;
else if (op == -1 && c > 1)
new_op = 1;
else
new_op = op;
dfs(streets, r, c, (changed ? time+2 : time+1), new_op);
visited[r][c] = false;
}
}
int main() {
int M;
int N;
cin >> M >> N;
vector<vector<char>> streets(M, vector<char>(N));
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++j) {
cin >> streets[i][j];
}
}
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++j) {
cout << streets[i][j] << " ";
}
cout << endl;
}
visited = vector<vector<bool>>(M, vector<bool>(N, false));
int r;
int c;
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++j) {
if (streets[i][j] == 'S') {
r = i;
c = j;
break;
}
}
}
dfs(streets, r, c, 0, -1);
if (min_time == INT32_MAX)
cout << -1 << endl;
else
cout << min_time << endl;
return 0;
}
反思一下:
1.出现段错的时候应该,抓紧启动调试,而不是傻傻的进行静态分析。
2.要先处理越界,再处理特殊情况
3.|| 运算符是全部都试一遍的,这跟&& 不同。
更新:时间复杂度更低的解法
//dfs+记忆化搜索
#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <string>
using namespace std;
vector<vector<bool>> visited;
vector<vector<int>> g_catch;
vector<pair<int, int>> off_set {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
bool ischange(vector<vector<char>> &streets, int r1, int c1, int r2, int c2, int op) {
//op == 1 遂平
//op == 0 竖直
if (op == -1)
false;
if (op == 0 && r1 == r2)
return true;
if (op == 1 && c1 == c2)
return true;
return false;
}
//将dfs的返回值定义为到达E所在街区的最小时间
int dfs(vector<vector<char>> &streets, int row, int colum, int op) {
cout << row << " " << colum << endl;
if (streets[row][colum] == 'E') {
return 0;
}
if (g_catch[row][colum] != -1)
return g_catch[row][colum];
int min_time = INT16_MAX;
for (auto &off : off_set) {
int r = row + off.first;
int c = colum + off.second;
if (r < 0 || r >= streets.size() || c < 0 || c >= streets[0].size() ) {
continue;
}
if (visited[r][c])
continue;
if (streets[r][c] == 'X')
continue;
visited[r][c] = true;
bool changed = ischange(streets, row, colum, r, c, op);
int new_op;
if (changed && op == 1)
new_op = 0;
else if (changed && op == 0)
new_op = 1;
else if (op == -1 && r > 1)
new_op = 0;
else if (op == -1 && c > 1)
new_op = 1;
else
new_op = op;
int t = dfs(streets, r, c, new_op);
int needtime = changed ? t + 2 : t + 1;
min_time = min(min_time, needtime);
visited[r][c] = false;
}
g_catch[row][colum] = min_time;
return min_time;
}
int main() {
int M = 6;
int N = 6;
vector<vector<char>> streets {{'S', 'B', 'B', 'B', 'B', 'B'},
{'B', 'X', 'X', 'X', 'X', 'B'},
{'B', 'B', 'X', 'B', 'B', 'B'},
{'X', 'B', 'B', 'X', 'X', 'B'},
{'B', 'B', 'B', 'B', 'X', 'B'},
{'B', 'B', 'X', 'B', 'E', 'B'}};
visited = vector<vector<bool>>(M, vector<bool>(N, false));
g_catch = vector<vector<int>>(M, vector<int>(N, -1));
int r;
int c;
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++j) {
if (streets[i][j] == 'S') {
r = i;
c = j;
break;
}
}
}
// cout << r << c << endl;
int ans = dfs(streets, r, c, -1);
if (ans == INT16_MAX)
cout << -1 << endl;
else
cout << ans << endl;
return 0;
}