๋ธ๋ก ์ด๋ํ๊ธฐ
โ โ โ โโ LEVEL 3
๋ฌธ์
๋ธ๋ก ์ด๋ํ๊ธฐ ๋ฌธ์ ๋งํฌ
๋ฌธ์ ์ค๋ช
๋ก๋ด๊ฐ๋ฐ์ ๋ฌด์ง๋ ํ ๋ฌ ์์ผ๋ก ๋ค๊ฐ์จ ์นด์นด์ค๋ฐฐ ๋ก๋ด๊ฒฝ์ง๋ํ์ ์ถํํ ๋ก๋ด์ ์ค๋นํ๊ณ ์์ต๋๋ค. ์ค๋น ์ค์ธ ๋ก๋ด์ 2 x 1 ํฌ๊ธฐ์ ๋ก๋ด์ผ๋ก ๋ฌด์ง๋ 0๊ณผ 1๋ก ์ด๋ฃจ์ด์ง N x N ํฌ๊ธฐ์ ์ง๋์์ 2 x 1 ํฌ๊ธฐ์ธ ๋ก๋ด์ ์์ง์ฌ (N, N) ์์น๊น์ง ์ด๋ ํ ์ ์๋๋ก ํ๋ก๊ทธ๋๋ฐ์ ํ๋ ค๊ณ ํฉ๋๋ค. ๋ก๋ด์ด ์ด๋ํ๋ ์ง๋๋ ๊ฐ์ฅ ์ผ์ชฝ, ์๋จ์ ์ขํ๋ฅผ (1, 1)๋ก ํ๋ฉฐ ์ง๋ ๋ด์ ํ์๋ ์ซ์ 0์ ๋น์นธ์ 1์ ๋ฒฝ์ ๋ํ๋ ๋๋ค. ๋ก๋ด์ ๋ฒฝ์ด ์๋ ์นธ ๋๋ ์ง๋ ๋ฐ์ผ๋ก๋ ์ด๋ํ ์ ์์ต๋๋ค. ๋ก๋ด์ ์ฒ์์ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ์ขํ (1, 1) ์์น์์ ๊ฐ๋ก๋ฐฉํฅ์ผ๋ก ๋์ฌ์๋ ์ํ๋ก ์์ํ๋ฉฐ, ์๋ค ๊ตฌ๋ถ์์ด ์์ง์ผ ์ ์์ต๋๋ค.
๋ก๋ด์ด ์์ง์ผ ๋๋ ํ์ฌ ๋์ฌ์๋ ์ํ๋ฅผ ์ ์งํ๋ฉด์ ์ด๋ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ ๊ทธ๋ฆผ์์ ์ค๋ฅธ์ชฝ์ผ๋ก ํ ์นธ ์ด๋ํ๋ค๋ฉด (1, 2), (1, 3) ๋ ์นธ์ ์ฐจ์งํ๊ฒ ๋๋ฉฐ, ์๋๋ก ์ด๋ํ๋ค๋ฉด (2, 1), (2, 2) ๋ ์นธ์ ์ฐจ์งํ๊ฒ ๋ฉ๋๋ค. ๋ก๋ด์ด ์ฐจ์งํ๋ ๋ ์นธ ์ค ์ด๋ ํ ์นธ์ด๋ผ๋ (N, N) ์์น์ ๋์ฐฉํ๋ฉด ๋ฉ๋๋ค.
๋ก๋ด์ ๋ค์๊ณผ ๊ฐ์ด ์กฐ๊ฑด์ ๋ฐ๋ผ ํ์ ์ด ๊ฐ๋ฅํฉ๋๋ค.
์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ๋ก๋ด์ 90๋์ฉ ํ์ ํ ์ ์์ต๋๋ค. ๋จ, ๋ก๋ด์ด ์ฐจ์งํ๋ ๋ ์นธ ์ค, ์ด๋ ์นธ์ด๋ ์ถ์ด ๋ ์ ์์ง๋ง, ํ์ ํ๋ ๋ฐฉํฅ(์ถ์ด ๋๋ ์นธ์ผ๋ก๋ถํฐ ๋๊ฐ์ ๋ฐฉํฅ์ ์๋ ์นธ)์๋ ๋ฒฝ์ด ์์ด์ผ ํฉ๋๋ค. ๋ก๋ด์ด ํ ์นธ ์ด๋ํ๊ฑฐ๋ 90๋ ํ์ ํ๋ ๋ฐ๋ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ์ ํํ 1์ด ์ ๋๋ค.
0๊ณผ 1๋ก ์ด๋ฃจ์ด์ง ์ง๋์ธ board๊ฐ ์ฃผ์ด์ง ๋, ๋ก๋ด์ด (N, N) ์์น๊น์ง ์ด๋ํ๋๋ฐ ํ์ํ ์ต์ ์๊ฐ์ return ํ๋๋ก solution ํจ์๋ฅผ ์์ฑํด์ฃผ์ธ์.
์ ํ์ฌํญ
- board์ ํ ๋ณ์ ๊ธธ์ด๋ 5 ์ด์ 100 ์ดํ์ ๋๋ค.
- board์ ์์๋ 0 ๋๋ 1์ ๋๋ค.
- ๋ก๋ด์ด ์ฒ์์ ๋์ฌ ์๋ ์นธ (1, 1), (1, 2)๋ ํญ์ 0์ผ๋ก ์ฃผ์ด์ง๋๋ค.
- ๋ก๋ด์ด ํญ์ ๋ชฉ์ ์ง์ ๋์ฐฉํ ์ ์๋ ๊ฒฝ์ฐ๋ง ์ ๋ ฅ์ผ๋ก ์ฃผ์ด์ง๋๋ค.
์ฝ๋
#include <string>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
int dirArray[12][4] = { { 0, 1, 0, 1 },{ 1, 0, 1, 0 },{ 0, -1, 0, -1 },{ -1, 0, -1, 0 },{ 1, 1, 0, 0 },{ 0, 0, -1, -1 },{ 0, 0, 1, -1 },{ -1, 1, 0, 0 },{ 1, 1, 0, 0 },{ 0, 0, -1, -1 },{ 1, -1, 0, 0 },{ 0, 0, -1, 1 } };
// ์ => ์ผ => ์ => ์ค => ๊ฐ๋กํ => ์ธ๋กํ
int row;
vector<vector<int>> board;
struct Robot { // ๊ณ์ฐ ํธํ๊ฒ struct ์ ์
int x; int y; int x2; int y2; int time;
Robot(int a, int b, int c, int d, int e) {
x = a; y = b; x2 = c; y2 = d; time = e;
}
};
bool isThereOkay(int r1, int c1, int r2, int c2) {
// ๋ฒ์ ๋ฐ ๋ฒฝ ์ฒดํฌ
if (r1<0 || c1<0 || r2<0 || c2<0)
return false;
if (r1 > row || r2 > row || c1 > row || c2 > row)
return false;
if (board[r1][c1] == 1 || board[r2][c2] == 1)
return false;
return true;
}
vector<int> whereCanIGo(Robot& pos) {
vector<int> candidate;
for (int i = 0; i<4; i++) {
pos.x += dirArray[i][0];
pos.y += dirArray[i][1];
pos.x2 += dirArray[i][0];
pos.y2 += dirArray[i][1];
if (isThereOkay(pos.x, pos.y, pos.x2, pos.y2)) {
candidate.push_back(i);
if (pos.x == pos.x2) { // ๊ฐ๋ก ๋ฐฐ์น์ผ ๋
if (i == 1) {
// ์๋์ชฝ์ผ๋ก ์ด๋ ๊ฐ๋ฅํ๋ฉด 4, 6๋ฒ์ ํ์ ๋ ๊ฐ๋ฅ
candidate.push_back(4);
candidate.push_back(6);
}
if (i == 3) {
// ์์ชฝ์ผ๋ก ์ด๋ ๊ฐ๋ฅํ๋ฉด 5, 7๋ฒ์ ํ์ ๋ ๊ฐ๋ฅ
candidate.push_back(5);
candidate.push_back(7);
}
}
else if (pos.y== pos.y2) { // ์ธ๋ก ๋ฐฐ์น
if (i == 0) {
candidate.push_back(8);
candidate.push_back(11);
}
if (i == 2) {
candidate.push_back(9);
candidate.push_back(10);
}
}
}
pos.x -= dirArray[i][0];
pos.y -= dirArray[i][1];
pos.x2 -= dirArray[i][0];
pos.y2 -= dirArray[i][1];
}
return candidate;
}
string makeKey(int ax, int ay, int bx, int by) {
if (ax > bx || (ax == bx && ay > by)) {
int tmp = ax;
int tmp2 = ay;
ax = bx; ay = by;
bx = tmp; by = tmp2;
}
return to_string(ax) + "/" + to_string(ay) + "//" + to_string(bx) + "/" + to_string(by);
}
int solution(vector<vector<int>> board2) {
int answer = 1e8;
board = board2; // ์ ์ญ ๋ณ์๋ก ์ฌ์ฉ
row = board.size() - 1; // ์ ์ญ ๋ณ์๋ก ์ฌ์ฉ
vector<string> visited;
queue<Robot> q;
Robot* first = new Robot(0, 0, 0, 1, 0);
q.push(*first); // ์ฒซ ์์น ์ ์ฅ
visited.push_back(makeKey(0, 0, 0, 1)); // ์ฒซ ์์น ๋ฐฉ๋ฌธ ๊ธฐ๋ก
while (q.size()) {
auto a = q.front(); q.pop(); // queue์ ๋ด๊ธด ์์น๋ฅผ ํ๋์ฉ ๋นผ๋ฉด์
if ((a.x == row && a.y == row) || (a.x2 == row && a.y2 == row)) { // ๋์ฐฉํ์ ๋
answer = a.time;
break;
}
vector<int> candidate = whereCanIGo(a); // ํ์ฌ ์์น์์ ์ด๋ํ ์ ์๋ ๊ณณ์ ์ ๋ณด ๋ฐ์์ค๊ธฐ
while(candidate.size()){
int idx = candidate.back(); candidate.pop_back();
int r1 = a.x + dirArray[idx][0];
int c1 = a.y + dirArray[idx][1];
int r2 = a.x2 + dirArray[idx][2];
int c2 = a.y2 + dirArray[idx][3];
if (r1 > r2 || (r1 == r2 && c1 > c2)) { // r1, c1์ด ์๊ฒ ์ ์ง
int tmp = r1; int tmp2 = c1;
r1 = r2; c1 = c2;
r2 = tmp; c2 = tmp2;
}
if (find(visited.begin(), visited.end(), makeKey(r1, c1, r2, c2)) != visited.end())
// ์ด๋ฏธ ๋ฐฉ๋ฌธํ๋ ๊ณณ์ด๋ฉด ๋ฐ์ด๋๊ธฐ
continue;
visited.push_back(makeKey(r1, c1, r2, c2)); // ์์น ๋ฐฉ๋ฌธ ๊ธฐ๋ก
Robot* tmp = new Robot(r1, c1, r2, c2, a.time + 1);
q.push(*tmp); // ๋ค์ ์์น ์ ์ฅ
}
}
return answer;
}
ํ์ด
์ด์ ๋ฌธ์ ์ ๋น์ทํ ๋งฅ๋ฝ์ผ๋ก ์ฝ์ด์, ๊ฐ ์์น์์ ๋ง์ง๋ง ๋์ฐฉ ๊ตฌ๊ฐ๊น์ง ๊ฐ๋ ์ต์ ๊ฒฝ๋ก๋ฅผ ์ ์ฅํด๋๊ณ ์ด์ฉํ๋ DP ๋ฌธ์ ๋ก ํ๋ ค๊ณ ํ๋ค. ์ ๋ ฅ๊ฐ๋ 10^2 ์ดํ๋ก ๊ทธ๋ค์ง ํฌ์ง ์์์ผ๋ฏ๋ก n^4๊น์ง๋ ๊ฐ๋ฅํ๋ค. DFS๋ก ์ฌ๊ท๋ฅผ ๋๋ฉด์ ์ด๋ฏธ ๋ฐฉ๋ฌธํ ๊ณณ์ด๋ฉด ์ ์ฅํด๋ ์ ๋ณด๋ฅผ ์ฐ๋ ๊ฒ์ผ๋ก ์๊ฐํ๊ณ ๋ฌธ์ ๋ฅผ ํ์๋ค.
ํ์ง๋ง DFS๋ก ํ๋ฉด ๊ณ์ ํ ์คํธ์ผ์ด์ค 6๋ฒ๋ถํฐ ํ๋ ธ๋ค๊ณ ๋์จ๋ค. ๊ทธ๋์ ์กฐ๊ฑด์ ๋๊ฐ์ด ํ๊ณ BFS๋ก ๋ฐ๊พธ์ด ํ์๋๋ ํต๊ณผ์๋ค.
ํ์ด ๋ฐฉ์์ ๋ค์๊ณผ ๊ฐ๋ค.
-
queue์ ๋ค์ ์ด๋ํ ์ ์๋ ์์น๋ค์ ๋ฃ๋๋ค.
-
์ด๋ํ ์ ์๋ ์์น๋ whereCanIGo ํจ์๊ฐ ํ๋จํ์ฌ ๋๊ฒจ์ค๋ค.
-
๋ฏธ๋ฆฌ ์ ์ํด๋ direction ๋ฐฐ์ด์ ์ด์ฉํ๋ค.
-
direction์๋ ๋ํด์ฃผ์ด์ผํ ์ซ์๋ค์ด ๋ค์ด๊ฐ ์์ผ๋ฉฐ, ๊ฐ index๋ฅผ ๊ทธ๋ฆผ์ผ๋ก ํํํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
-
-
-
์ค๊ฐ์ ๊ฐ๋ก ๋ฐฐ์น์ผ ๋, ์ธ๋ก ๋ฐฐ์น์ผ ๋๋ฅผ ๋๋์ด๋ ๊ฒ์ ํ์ ์ ๊ณ ๋ คํ๊ธฐ ์ํด์์ด๋ค.
-
์๋ฅผ ๋ค์ด, 1๋ฒ์ ์ด๋(์๋๋ก์ ์ด๋)์ด ๊ฐ๋ฅํ๋ฉด ์๋ ๋ฐฉํฅ์ผ๋ก์ ํ์ ๋ ๊ฐ๋ฅํ๋ค.
-
๋ฐ๋ผ์, ๊ฐ๋ก๋ฐฉํฅ์ผ ๋ i๊ฐ 1์ด๋ฉด 4์ 6๋ ํจ๊ป ํ๋ณด์ ๋ฃ์ด์ฃผ๋ ๊ฒ์ด๋ค.
-
-
-
์ด๋ํ ์ ์๋ ์์น๋ค์ ํ๋์ฉ ๋ฐ์ํ๋ฉด์ ๋ฐฉ๋ฌธ ๋ฐ ์๊ฐ์ ๊ธฐ๋กํ๋ค.
- ๋ฐฉ๋ฌธ ์ฌ๋ถ๋ visited ๋ฐฐ์ด์ string์ ํํ๋ก ์ ์ฅํ์๋ค.
- string์ makeKey ํจ์๊ฐ ๋ง๋ค์ด ์ฃผ๋ฉฐ, ์ฃผ์ด์ง ์ขํ๋ฅผ ์ด์ฉํด์ key๋ฅผ ์์ฑํด์ค๋ค.
- ํด๋น ํค๋ ์์น์ ๋ํด uniqueํ๋ฉฐ ์ด๋ฅผ ๋ณด์ฅํ๊ธฐ ์ํด ํค๋ฅผ ์์ฑํ๊ธฐ ์ ์ ๋ ฌ์ ํด์ค๋ค.
-
๋ง์ง๋ง ์์น์ ๋๋ฌํ์๋ค๋ฉด ๋ค์ ๊ฒฝ๋ก๋ฅผ ์ดํด๋ณด๊ธฐ๋ฅผ ๊ทธ๋ง๋๊ณ ๋ต์ ๋ธ๋ค.
์ต๋จ๊ฒฝ๋ก ๋ฌธ์ ์์ DFS๋ณด๋ค BFS๋ฅผ ์ฐ๋ ์ด์
DFS ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
#include <string>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
int row = 0; int col = 0;
vector<vector<int>> board;
map<string, int> memo;
int direction[12][4] = { {1, 0, 1, 0}, {0, -1, 0, -1}, {-1, 0, -1, 0}, {0, 1, 0, 1}, {1, 1, 0, 0}, {0, 0, -1, -1}, {0, 0, 1, -1}, {-1, 1, 0, 0},{ 1, 1, 0, 0 },{ 0, 0, -1, -1 },{ 1, -1, 0, 0 },{ 0, 0, -1, 1 } };
// ์ => ์ผ => ์ => ์ค => ๊ฐ๋กํ => ์ธ๋กํ
bool compare(pair<int, int> p1, pair<int, int> p2) {
// ... ์์ ๊ฐ์
}
bool isThereOkay(vector<pair<int, int>> pos) {
// ... ์์ ๊ฐ์
}
vector<int> whereCanIGo(vector<pair<int, int>>& pos) {
// ... ์์ ๊ฐ์
}
string makeKey(int ax, int ay, int bx, int by) {
// ... ์์ ๊ฐ์
}
int leastMove(vector<pair<int, int>>& pos) {
if ((pos[0].first == row && pos[0].second == col) | (pos[1].first == row && pos[1].second == col))
return 0;
vector<int> candidate = whereCanIGo(pos);
int max = 1e8;
if (candidate.size() == 0)
return 1e8;
while (candidate.size()) {
int idx = candidate.back(); candidate.pop_back();
int tmp_ans = 0;
vector<pair<int, int>> next_pos;
next_pos.push_back(make_pair(pos[0].first + direction[idx][0], pos[0].second + direction[idx][1]));
next_pos.push_back(make_pair(pos[1].first + direction[idx][2], pos[1].second + direction[idx][3]));
sort(next_pos.begin(), next_pos.end(), compare);
string key_str = makeKey(next_pos[0].first, next_pos[0].second, next_pos[1].first, next_pos[1].second);
if (memo.find(key_str)!=memo.end())
tmp_ans += memo[key_str];
else {
memo[key_str] = 1e8; // ๊ฐ์ ์์น ๋ฐฉ๋ฌธํ์ง ์๋๋ก ํ๊ธฐ
int ret = leastMove(next_pos);
memo[key_str] = ret; tmp_ans += ret;
}
if (max>tmp_ans)
max = tmp_ans;
}
return max+1;
}
int solution(vector<vector<int>> board2) {
int answer = 0;
row = board2.size()-1;
col = board2[0].size()-1;
board = board2;
vector<pair<int, int>> pos;
pos.push_back(make_pair(0, 0));
pos.push_back(make_pair(0, 1));
memo[makeKey(0, 0, 0, 1)] = 1e8;
answer = leastMove(pos);
return answer;
}
๋ค๋ฅธ ๋ถ๋ถ์ด๋ผ๊ณ ํ๋ค๋ฉด, ์ฌ๊ท๋ก ๋๋ ค์ DFS๋ฅผ ์ํํ ๊ฒ์ด๋ค. DFS๋ ํ ๊ฒฝ๋ก๋ฅผ ๋ชจ๋ ํ์ ํ ๋ค๋ฅธ ๊ฒฝ๋ก๋ฅผ ํ์ํ๊ธฐ ๋๋ฌธ์, ํ ๊ฒฝ๋ก๋ฅผ ํ์ํ ๋ ๊ฐ์ ์์น๋ฅผ ๋ฐฉ๋ฌธํ์ง ์๋๋ก ํ๊ธฐ ์ํด์ ๋ฉ๋ชจ์ด์ ์ด์ ์ ๊ฐ์ฅ ํฐ ๊ฐ์ ๋ฃ๋ ์์ผ๋ก ์ฒ๋ฆฌํ์๋ค.
https://www.acmicpc.net/board/view/27666
์์ ๋งํฌ๋ฅผ ์ฐธ์กฐํด๋ณด๋ฉด, BFS์ DFS ๋ชจ๋ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ณ ๋ คํ ์ ์์ง๋ง BFS๋ ์ต๋จ๊ฑฐ๋ฆฌ๋ฅผ ์ฐพ์๋ง์ ์ข ๋ฃํ ์ ์๊ธฐ ๋๋ฌธ์ ์ต๋จ ๊ฒฝ๋ก ๋ฌธ์ ์์๋ ์ฃผ๋ก BFS๋ฅผ ์ด์ฉํ๋ค๊ณ ํ๋ค. ํด๋น ๋ฌธ์ ๋ ์ต๋จ ์๊ฐ์ ๊ณ์ฐํ๊ธฐ๋ง ํ๋ฉด ๋๋ ๋ฌธ์ ์ด๋ฏ๋ก BFS๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ์ ํฉํ๋ค.
์์ ๋ธ๋ก๊ทธ๋ฅผ ์ฐธ์กฐํด๋ณด๋ฉด, DFS๋ ์ต์ ์ ๊ฒฝ๋ก๊ฐ ์ฌ๋ฌ ๊ฐ ์๋ ๊ฒฝ์ฐ์ ํ์์ ๋๋ด๋ฒ๋ ค์ผํ๊ธฐ ๋๋ฌธ์ ๋๋ค๋ฅธ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ ์ ์๋ค. BFS๋ ํด์ ๋๋ฌํ์๋๋ผ๋ ์ข ๋ฃํ์ง ์๊ณ , ๊ณ์ํด์ ์งํ ๊ฐ๋ฅํ๋ค.
์๋ฅผ ๋ค์ด, ์ด์ ๊ฐ์ ๊ทธ๋ํ ์์ ์์ A => B์ ๊ฒฝ๋ก๋ ์์ธกํ ์ ์๋ ๊ฒ์ด๋ค. ๋ณธ์ธ์ ์ฝ๋์์๋ ์ด๋ฏธ ๋ค๋ฅธ ์ง์ ์ ๊ฐ์ฅ ํฐ ์ ๋๋ ๋ง์ง๋ง ์ง์ ๊น์ง์ ๊ฒฝ๋ก๋ก ํ์ํด๋ฒ๋ฆฌ๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ ์ ์๋ค.
์ฑ์ ๊ฒฐ๊ณผ
์๊ฐ์ ๊ทธ๋ค์ง ์ ๋์จ ๊ฒ ๊ฐ์ง ์๋ค.
์ฃผ์ ์ฌํญ
- ์ด๋ ๊ฒ ๋ณต์กํ ์กฐ๊ฑด์ด ์ฃผ์ด์ง ๋๋ struct๋ฅผ ์ด์ฉํ๋ ๊ฒ์ด ๋ ๊ฐํธํ๋ค.
- ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ๊ธฐ๋ง ํ๋ฉด ๋๋ ๋ฌธ์ ์์๋ BFS๊ฐ ์ ์ฉํ๋ค.
๋ค๋ฅธ ์ฌ๋์ ํ์ด
- ๋ฐฉํฅ์ ๋ณ์๋ก ์ก์์ visited๋ฅผ ๊ตฌํํ๋๋ฐ, ๊ทธ๋ ๊ฒ ํ๋ฉด ํ ์ขํ์์ ์ค๋ฅธ์ชฝ ๋ฐฉํฅ์ธ ๊ฒ๊ณผ ๋ฐ๋ ์ขํ์์ ์ผ์ชฝ ๋ฐฉํฅ์ธ ๊ฒ (๊ฒฐ๊ตญ ๋๊ฐ์ ๊ฒ)์ ์ด๋ป๊ฒ ๊ตฌ๋ถํ๋ ์ง ์๋ฌธ์ด๋ค. ๊ทธ๋ฅ ๋ฌด์ํ๊ณ ์ฌ๋ฌ ๋ฒ ๊ฒ์ฌํ ์๊ฐํ๊ณ ๋ฉ๋ชจ์ด์ ์ด์ ์ ํ๋ ๊ฒ์ธ๊ฐ?
Comment