알고리즘
Judge - 1237 : 2보 전진을 위한 1보 후퇴 C++
영춘권의달인
2022. 7. 13. 16:38
두가지 방법으로 풀었다.
1. 실제로 2보 전진, 1보 후퇴하는식으로 bfs탐색으로 해결
2. 그냥 bfs탐색을 하면서 parent를 이용해서 경로를 저장한 뒤, 도착지점에서 출발지점으로 2보전진 1보후퇴
출발지점이 벽인 경우를 처음에 고려를 안해서 계속 틀리다보니 고민을 계속 하다가 두가지 방법이 나오게 되었다.
출발지점이 벽인 경우를 고려하면 둘 다 맞는 답이다.
#include <iostream>
#include <string>
#include <vector>
#include <math.h>
#include <algorithm>
#include <utility>
#include <stack>
#include <queue>
#include <math.h>
#include <set>
#include <map>
#include <list>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <limits.h>
using namespace std;
using int64 = long long;
int n;
struct location {
int row;
int col;
int cnt;
};
int dRow[4] = { -1,0,1,0 };
int dCol[4] = { 0,1,0,-1 };
vector<vector<int>> board;
vector<vector<bool>> found;
pair<int, int> start = { 0,0 };
pair<int, int> target;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n;
board = vector<vector<int>>(n, vector<int>(n));
found = vector<vector<bool>>(n, vector<bool>(n, false));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> board[i][j];
}
}
target = { n - 1,n - 1 };
if (board[start.first][start.second] == 0 || board[target.first][target.second] == 0) {
cout << "-1" << "\n";
return 0;
}
queue<location> q;
q.push({ start.first,start.second,0 });
found[start.first][start.second] = true;
while (!q.empty()) {
auto curr = q.front();
q.pop();
bool isReached = false;
int ans = INT_MAX;
for (int i = 0; i < 4; i++) {
int nextRow = curr.row + dRow[i];
int nextCol = curr.col + dCol[i];
int nextCnt = curr.cnt + 1;
if (nextRow < 0 || nextRow >= n) continue;
if (nextCol < 0 || nextCol >= n) continue;
if (board[nextRow][nextCol] == 0) continue;
if (found[nextRow][nextCol]) continue;
if (nextRow == target.first && nextCol == target.second) {
isReached = true;
ans = min(ans, nextCnt);
}
for (int j = 0; j < 4; j++) {
int nnextRow = nextRow + dRow[j];
int nnextCol = nextCol + dCol[j];
int nnextCnt = nextCnt + 1;
if (nnextRow < 0 || nnextRow >= n) continue;
if (nnextCol < 0 || nnextCol >= n) continue;
if (board[nnextRow][nnextCol] == 0) continue;
if (found[nnextRow][nnextCol]) continue;
if (nnextRow == target.first && nnextCol == target.second) {
isReached = true;
ans = min(ans, nnextCnt);
}
q.push({ nextRow,nextCol,nnextCnt + 1 });
found[nextRow][nextCol] = true;
}
}
if (isReached) {
cout << ans << "\n";
return 0;
}
}
cout << -1 << "\n";
}
#include <iostream>
#include <string>
#include <vector>
#include <math.h>
#include <algorithm>
#include <utility>
#include <stack>
#include <queue>
#include <math.h>
#include <set>
#include <map>
#include <list>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <limits.h>
using namespace std;
using int64 = long long;
int n;
int dRow[4] = { -1,0,1,0 };
int dCol[4] = { 0,1,0,-1 };
vector<vector<int>> board;
vector<vector<bool>> found;
vector<vector<pair<int, int>>> parent;
pair<int, int> start = { 0,0 };
pair<int, int> target;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n;
board = vector<vector<int>>(n, vector<int>(n));
found = vector<vector<bool>>(n, vector<bool>(n, false));
parent = vector<vector<pair<int, int>>>(n, vector<pair<int, int>>(n));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> board[i][j];
}
}
target = { n - 1,n - 1 };
if (board[start.first][start.second] == 0 || board[target.first][target.second] == 0) {
cout << "-1" << "\n";
return 0;
}
queue<pair<int, int>> q;
q.push({ start.first,start.second});
found[start.first][start.second] = true;
parent[start.first][start.second] = start;
bool isPossible = false;
while (!q.empty()) {
auto curr = q.front();
q.pop();
if (curr.first == target.first && curr.second == target.second) {
isPossible = true;
break;
}
for (int i = 0; i < 4; i++) {
int nextRow = curr.first + dRow[i];
int nextCol = curr.second + dCol[i];
if (nextRow < 0 || nextRow >= n) continue;
if (nextCol < 0 || nextCol >= n) continue;
if (board[nextRow][nextCol] == 0) continue;
if (found[nextRow][nextCol]) continue;
q.push({ nextRow,nextCol });
found[nextRow][nextCol] = true;
parent[nextRow][nextCol] = { curr.first,curr.second };
}
}
if (!isPossible) {
cout << "-1" << "\n";
return 0;
}
pair<int, int> curr = target;
int cnt = 0;
while (true) {
if (curr == start) break;
cnt++;
pair<int, int> _parent = parent[curr.first][curr.second];
if (_parent == start) break;
cnt++;
pair<int, int> _pparent = parent[_parent.first][_parent.second];
if (_pparent == start) break;
cnt++;
curr = _parent;
}
cout << cnt << "\n";
}