๐ง ํ๋ก๊ทธ๋๋จธ์ค LV3. ์นด๋ ์ง ๋ง์ถ๊ธฐ
๋ฌธ์ ์ค๋ช
๊ฒ์ ๊ฐ๋ฐ์์ธ ๋ฒ ๋ก๋๋ ๊ฐ๋ฐ ์ฐ์ต์ ์ํด ๋ค์๊ณผ ๊ฐ์ ๊ฐ๋จํ ์นด๋ ์ง๋ง์ถ๊ธฐ ๋ณด๋ ๊ฒ์์ ๊ฐ๋ฐํด ๋ณด๋ ค๊ณ ํฉ๋๋ค.๊ฒ์์ด ์์๋๋ฉด ํ๋ฉด์๋ ์นด๋ 16์ฅ์ด ๋ท๋ฉด์ ์๋กํ์ฌ 4 x 4 ํฌ๊ธฐ์ ๊ฒฉ์ ํํ๋ก ํ์๋์ด ์์ต๋๋ค. ๊ฐ ์นด๋์ ์๋ฉด์๋ ์นด์นด์คํ๋ ์ฆ ์บ๋ฆญํฐ ๊ทธ๋ฆผ์ด ๊ทธ๋ ค์ ธ ์์ผ๋ฉฐ, 8๊ฐ์ง์ ์บ๋ฆญํฐ ๊ทธ๋ฆผ์ด ๊ทธ๋ ค์ง ์นด๋๊ฐ ๊ฐ๊ธฐ 2์ฅ์ฉ ํ๋ฉด์ ๋ฌด์์๋ก ๋ฐฐ์น๋์ด ์์ต๋๋ค.์ ์ ๊ฐ ์นด๋๋ฅผ 2์ฅ ์ ํํ์ฌ ์๋ฉด์ผ๋ก ๋ค์ง์์ ๋ ๊ฐ์ ๊ทธ๋ฆผ์ด ๊ทธ๋ ค์ง ์นด๋๋ฉด ํด๋น ์นด๋๋ ๊ฒ์ ํ๋ฉด์์ ์ฌ๋ผ์ง๋ฉฐ, ๊ฐ์ ๊ทธ๋ฆผ์ด ์๋๋ผ๋ฉด ์๋ ์ํ๋ก ๋ท๋ฉด์ด ๋ณด์ด๋๋ก ๋ค์งํ๋๋ค. ์ด์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ๋ชจ๋ ์นด๋๋ฅผ ํ๋ฉด์์ ์ฌ๋ผ์ง๊ฒ ํ๋ฉด ๊ฒ์์ด ์ข ๋ฃ๋ฉ๋๋ค.
๊ฒ์์์ ์นด๋๋ฅผ ์ ํํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ์นด๋๋ ์ปค์๋ฅผ ์ด์ฉํด์ ์ ํํ ์ ์์ต๋๋ค.
- ์ปค์๋ 4 x 4 ํ๋ฉด์์ ์ ์ ๊ฐ ์ ํํ ํ์ฌ ์์น๋ฅผ ํ์ํ๋ "๊ตต๊ณ ๋นจ๊ฐ ํ ๋๋ฆฌ ์์"๋ฅผ ์๋ฏธํฉ๋๋ค.
- ์ปค์๋ [Ctrl] ํค์ ๋ฐฉํฅํค์ ์ํด ์ด๋๋๋ฉฐ ํค ์กฐ์๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ๋ฐฉํฅํค ←, ↑, ↓, → ์ค ํ๋๋ฅผ ๋๋ฅด๋ฉด, ์ปค์๊ฐ ๋๋ฅธ ํค ๋ฐฉํฅ์ผ๋ก 1์นธ ์ด๋ํฉ๋๋ค.
- [Ctrl] ํค๋ฅผ ๋๋ฅธ ์ํ์์ ๋ฐฉํฅํค ←, ↑, ↓, → ์ค ํ๋๋ฅผ ๋๋ฅด๋ฉด, ๋๋ฅธ ํค ๋ฐฉํฅ์ ์๋ ๊ฐ์ฅ ๊ฐ๊น์ด ์นด๋๋ก ํ๋ฒ์ ์ด๋ํฉ๋๋ค.
- ๋ง์ฝ, ํด๋น ๋ฐฉํฅ์ ์นด๋๊ฐ ํ๋๋ ์๋ค๋ฉด ๊ทธ ๋ฐฉํฅ์ ๊ฐ์ฅ ๋ง์ง๋ง ์นธ์ผ๋ก ์ด๋ํฉ๋๋ค.
- ๋ง์ฝ, ๋๋ฅธ ํค ๋ฐฉํฅ์ผ๋ก ์ด๋ ๊ฐ๋ฅํ ์นด๋ ๋๋ ๋น ๊ณต๊ฐ์ด ์์ด ์ด๋ํ ์ ์๋ค๋ฉด ์ปค์๋ ์์ง์ด์ง ์์ต๋๋ค.
- ์ปค์๊ฐ ์์นํ ์นด๋๋ฅผ ๋ค์ง๊ธฐ ์ํด์๋ [Enter] ํค๋ฅผ ์ ๋ ฅํฉ๋๋ค.
- [Enter] ํค๋ฅผ ์ ๋ ฅํด์ ์นด๋๋ฅผ ๋ค์ง์์ ๋
- ์๋ฉด์ด ๋ณด์ด๋ ์นด๋๊ฐ 1์ฅ ๋ฟ์ด๋ผ๋ฉด ๊ทธ๋ฆผ์ ๋ง์ถ ์ ์์ผ๋ฏ๋ก ๋๋ฒ์งธ ์นด๋๋ฅผ ๋ค์ง์ ๋ ๊น์ง ์๋ฉด์ ์ ์งํฉ๋๋ค.
- ์๋ฉด์ด ๋ณด์ด๋ ์นด๋๊ฐ 2์ฅ์ด ๋ ๊ฒฝ์ฐ, ๋๊ฐ์ ์นด๋์ ๊ทธ๋ ค์ง ๊ทธ๋ฆผ์ด ๊ฐ์ผ๋ฉด ํด๋น ์นด๋๋ค์ด ํ๋ฉด์์ ์ฌ๋ผ์ง๋ฉฐ, ๊ทธ๋ฆผ์ด ๋ค๋ฅด๋ค๋ฉด ๋ ์นด๋ ๋ชจ๋ ๋ท๋ฉด์ด ๋ณด์ด๋๋ก ๋ค์ ๋ค์งํ๋๋ค.
"๋ฒ ๋ก๋"๋ ๊ฒ์ ์งํ ์ค ์นด๋์ ์ง์ ๋ง์ถฐ ๋ช ์ฅ ์ ๊ฑฐ๋ ์ํ์์ ์นด๋ ์๋ฉด์ ๊ทธ๋ฆผ์ ์๊ณ ์๋ค๋ฉด, ๋จ์ ์นด๋๋ฅผ ๋ชจ๋ ์ ๊ฑฐํ๋๋ฐ ํ์ํ ํค ์กฐ์ ํ์์ ์ต์๊ฐ์ ๊ตฌํด ๋ณด๋ ค๊ณ ํฉ๋๋ค. ํค ์กฐ์ ํ์๋ ๋ฐฉํฅํค์ [Enter] ํค๋ฅผ ๋๋ฅด๋ ๋์์ ๊ฐ๊ฐ ์กฐ์ ํ์ 1๋ก ๊ณ์ฐํ๋ฉฐ, [Ctrl] ํค์ ๋ฐฉํฅํค๋ฅผ ํจ๊ป ๋๋ฅด๋ ๋์ ๋ํ ์กฐ์ ํ์ 1๋ก ๊ณ์ฐํฉ๋๋ค.
ํ์ฌ ์นด๋๊ฐ ๋์ธ ์ํ๋ฅผ ๋ํ๋ด๋ 2์ฐจ์ ๋ฐฐ์ด board์ ์ปค์์ ์ฒ์ ์์น r, c๊ฐ ๋งค๊ฐ๋ณ์๋ก ์ฃผ์ด์ง ๋, ๋ชจ๋ ์นด๋๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํ ํค ์กฐ์ ํ์์ ์ต์๊ฐ์ return ํ๋๋ก solution ํจ์๋ฅผ ์์ฑํด ์ฃผ์ธ์.
์ ํ ์ฌํญ
- board๋ 4 x 4 ํฌ๊ธฐ์ 2์ฐจ์ ๋ฐฐ์ด์ ๋๋ค.
- board ๋ฐฐ์ด์ ๊ฐ ์์๋ 0 ์ด์ 6 ์ดํ์ธ ์์ฐ์์ ๋๋ค.
- 0์ ์นด๋๊ฐ ์ ๊ฑฐ๋ ๋น ์นธ์ ๋ํ๋ ๋๋ค.
- 1 ๋ถํฐ 6๊น์ง์ ์์ฐ์๋ 2๊ฐ์ฉ ๋ค์ด์์ผ๋ฉฐ ๊ฐ์ ์ซ์๋ ๊ฐ์ ๊ทธ๋ฆผ์ ์นด๋๋ฅผ ์๋ฏธํฉ๋๋ค.
- ๋ค์ง์ ์นด๋๊ฐ ์๋ ๊ฒฝ์ฐ(board์ ๋ชจ๋ ์์๊ฐ 0์ธ ๊ฒฝ์ฐ)๋ ์ ๋ ฅ์ผ๋ก ์ฃผ์ด์ง์ง ์์ต๋๋ค.
- r์ ์ปค์์ ์ต์ด ์ธ๋ก(ํ) ์์น๋ฅผ ์๋ฏธํฉ๋๋ค.
- c๋ ์ปค์์ ์ต์ด ๊ฐ๋ก(์ด) ์์น๋ฅผ ์๋ฏธํฉ๋๋ค.
- r๊ณผ c๋ 0 ์ด์ 3 ์ดํ์ธ ์ ์์ ๋๋ค.
- ๊ฒ์ ํ๋ฉด์ ์ข์ธก ์๋จ์ด (0, 0), ์ฐ์ธก ํ๋จ์ด (3, 3) ์ ๋๋ค.
์ ์ถ๋ ฅ ์
board | r | c | result |
[[1,0,0,3],[2,0,0,0],[0,0,0,2],[3,0,1,0]] | 1 | 0 | 14 |
[[3,0,0,2],[0,0,1,0],[0,1,0,0],[2,0,0,3]] | 0 | 1 | 16 |
https://school.programmers.co.kr/learn/courses/30/lessons/72415
๐ก ๋ฌธ์ ํ์ด
์นด์นด์ค ์ฝํ ๊ธฐ์ถ๋ต๊ฒ ๋ฌธ์ ์ดํด๋ถํฐ ์ด๋ ค์ ๊ณ , ์ ๋ต ํ์ด ๋ฐฉ์์ ์ดํดํ๋ ๋ฐ๋ ํ์ฐธ ๊ฑธ๋ ธ๋ค. ๐ฆ
๊ตฌํ, ์์ด, bfs ์ ํ์ด ๋ชจ๋ ์์ธ ๋ฌธ์ ์๋ค. ์์ด๊ณผ bfs ๊ฐ๋ ์ ์๊ณ ์๋ค๋ ๊ฐ์ ํ์ ๋ฌธ์ ํ์ด๋ฅผ ์ ์ด๋ณด๋๋ก ํ๊ฒ ๋ค.
์ฐ์ ์์ฝ์ ํด๋ณด์๋ฉด,,,
๊ฒ์ํ(board)์ ์๋ ์ซ์ ์นด๋๋ฅผ ์ฐพ๋ ์์๋ฅผ ์์ด๋ก ๊ตฌํด์ ๊ฐ bfs ์๊ณ ๋ฆฌ์ฆ์ ๋๋ฆฐ๋ค.
์นด๋๋ฅผ ํ๋์ฉ ์ฐพ์ ๋๋ง๋ค ์ต์ ๊ฑฐ๋ฆฌ๋ฅผ ๋ํด์ฃผ๊ณ , ํ๋ฅผ ๋น์์ฃผ๊ณ ๋ค์ ์นด๋๋ฅผ ์ฐพ์ ๋ค์ ์์ํ๋ค.
๋ชจ๋ ์นด๋๋ฅผ ์ฐพ์์ผ๋ฉด ์ ์ญ ๋ณ์ answer(๋ชจ๋ ๊ฒฝ์ฐ์ ๊ฐ ์ค ์ต์๊ฐ)๊ณผ ๋น๊ตํด์ ์ต์๊ฐ์ผ๋ก ์ ๋ฐ์ดํธ ํด์ค๋ค.
ํ์ํ ์ ์ญ ๋ณ์๋ค์ ์ ์ํ๋ค.
static boolean[] isNum = new visited[7]; // ์ซ์ ์นด๋: ๊ฒ์ํ์ ์์ผ๋ฉด true, ์๋๋ฉด false
static boolean[] visited = new visited[7]; // ์์ด์์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฌธ ์ฒดํฌ ๋ฐฐ์ด
static int size = 0; // ์กด์ฌํ๋ ์ซ์ ์นด๋ ๊ฐ์ (์ค๋ณต์์ด)
static int answer = Integer.MAX_VALUE; // ๋ฌธ์ ๋ต: ์ต์ ํค ์กฐ์ ํ์
static int[] dx = {1, -1, 0, 0};
static int[] dy = {0, 0, 1, -1};
static class Point { // ๊ฒ์ํ ๋ด ์์น
int x, y, d;
Point(int x, int y, int d) {
this.x = x; // row
this.y = y; // column
this.d = d; // ์ด๋ ๊ฑฐ๋ฆฌ(ํค ์กฐ์ ํ์)
}
}
solution ๋ฉ์๋
public int solution(int[][] board, int r, int c) {
// ๊ฒ์ํ์ ์๋ ์นด๋ ํ์ธ
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
// ์นด๋๊ฐ ์๋ ์นธ์ด๊ฑฐ๋, ์ด๋ฏธ ํ์ธํ ์นด๋ ์ข
๋ฅ์ด๋ฉด pass
if(board[i][j] == 0 || isNum[board[i][j]]) continue;
isNum[board[i][j]] = true; // ์นด๋ ์กด์ฌ ํ์ธ
size++; // ์นด๋ ์ข
๋ฃ ๊ฐ์ + 1
}
}
// ์์ด: ์นด๋ ํ์ ์์
permutation(0, new int[size], board, r, c);
// ๋ชจ๋ ํ์์ ๊ฒฝ์ฐ์ ์์์ ์ต์ ์กฐ์ ๊ฐ์ ๊ฐ ๋ฐํ
return answer;
}
permutation ๋ฉ์๋ : ์์ด, ์นด๋ ํ์ ์์๋ฅผ ๊ตฌํ๋ค.
// cnt: ๋ฝ์ ์ ๊ฐ์, arr: ์นด๋ ํ์ ์์
private void permutation(int cnt, int[] arr, int[][] board, int r, int c) {
if(size == cnt) { // ์์ด ๋๋ฌ์ผ๋ฉด arr ์์๋๋ก bfs ๋๋ฆฌ๊ธฐ
bfs(board, r, c, arr);
return;
}
for(int i = 1; i <= 6; i++) {
if(visited[i] || !isNum[i]) continue; // ์๋ ์นด๋์ด๊ฑฐ๋ ๋ฐฉ๋ฌธํ์ผ๋ฉด pass
visited[i] = true;
arr[cnt] = i;
permutation(cnt + 1, arr, board, r, c);
visited[i] = false;
}
}
bfs ๋ฉ์๋ : ์์๋๋ก ์นด๋๋ฅผ ํ์ํ๋ฉด์ ์ต์ ํค ์กฐ์ ํ์๋ฅผ ๊ตฌํ๋ค.
private void bfs(int[][] board, int r, int c, int[] arr) {
// ์์น ์ ๋ณด ํ
Queue<Point> queue = new LinkedList<>();
queue.add(new Point(r, c, 0));
// ์์น ๋ฐฉ๋ฌธ ์ฌ๋ถ ์ ์ฅ
boolean[][] isVisited = new boolean[4][4];
isVisited[r][c] = true;
// ์นด๋๋ฅผ ์ฐพ์๋์ง(enter) ์ฌ๋ถ ์ ์ฅ
boolean[][] enterVisited = new boolean[4][4];
int answerCnt = 0; // ์ ์ฒด ํค ์กฐ์ ํ์
int idx = 0; // ์นด๋ ํ์ ์์ ๋ฐฐ์ด ์ธ๋ฑ์ค
boolean isSecond = false; // ๋๋ฒ์งธ ์นด๋ ํ์ ์ฌ๋ถ
while(!queue.isEmpty()) {
Point cur = queue.poll();
// ์ฐพ๊ณ ์ํ๋(arr[idx]) ์นด๋๋ฅผ ์ฒ์(!enterVisited) ์ฐพ์์ ๋
if(board[cur.x][cur.y] == arr[idx] && !enterVisited[cur.x][cur.y]) {
enterVisited[cur.x][cur.y] = true;
answerCnt++; // enter ํค
answerCnt += cur.d; // ์ต๋จ ์ด๋ ๊ฑฐ๋ฆฌ ๋ํ๊ธฐ
// ํ ์ด๊ธฐํ (๋ค์ ์นด๋ ํ์ ์์ ์ค๋น)
queue.clear();
queue.add(new Point(cur.x, cur.y, 0));
isVisited = new boolean[4][4];
isVisited[cur.x][cur.y] = true;
if(!isSecond) { // ๊ฐ์ ์ข
๋ฅ์์ ์ฒซ๋ฒ์งธ๋ก ์ฐพ์ ์นด๋์ผ ๋
isSecond = true;
} else { // ๋๋ฒ์งธ๋ก ์ฐพ์ ์นด๋์ผ ๋
isSecond = false;
idx++; // ๋ค์ ์นด๋ ์ ํ
if(idx >= arr.length) { // ๋ชจ๋ ์นด๋๋ฅผ ์ฐพ์์ ๋
answer = Math.min(answer, answerCnt); // ์ต์๊ฐ ์
๋ฐ์ดํธ
return;
}
}
continue;
}
for(int i = 0; i < 4; i++) {
int nx = cur.x + dx[i];
int ny = cur.y + dy[i];
// ํ ์นธ ์ด๋
if(0 <= nx && nx < 4 && 0 <= ny && ny < 4 && !isVisited[nx][ny]) {
isVisited[nx][ny] = true;
queue.add(new Point(nx, ny, cur.d + 1));
}
// ํ ์นธ ์ด๋ํ๊ธฐ ์ ์์น๋ก ๋ค์ ์ด๊ธฐํ
nx -= dx[i];
ny -= dy[i];
// ctrl ์ด์ฉํด์ ๋๊น์ง ์ด๋
while(0 <= nx + dx[i] && nx + dx[i] < 4 && 0 <= ny + dy[i] && ny + dy[i] < 4) {
nx += dx[i];
ny += dy[i];
// ์ค๊ฐ์ enter ํ์ง ์์ ์นด๋๊ฐ ์๋ค๋ฉด ๋ฉ์ถค
if(board[nx][ny] != 0 && !enterVisited[nx][ny]) {
break;
}
}
// ctrl ์ด๋
if(0 <= nx && nx < 4 && 0 <= ny && ny < 4 && !isVisited[nx][ny]) {
isVisited[nx][ny] = true;
queue.add(new Point(nx, ny, cur.d + 1));
}
}
}
}
ํ์ด ๋ฐฉ์์ ์ ์ฒด ์ฝ๋๋ก ํ์ด๋ด๋ฉด ์๋์ ๊ฐ๋ค.
import java.util.*;
class Solution {
static boolean[] isNum = new boolean[7];
static boolean[] visited = new boolean[7];
static int size = 0;
static int answer = Integer.MAX_VALUE;
static int[] dx = {1, -1, 0, 0};
static int[] dy = {0, 0, 1, -1};
static class Point {
int x;
int y;
int d;
Point(int x, int y, int d) {
this.x = x;
this.y = y;
this.d = d;
}
}
public int solution(int[][] board, int r, int c) {
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
if(board[i][j] == 0 || isNum[board[i][j]]) {
continue;
}
isNum[board[i][j]] = true;
size++;
}
}
permutation(0, new int[size], board, r, c);
return answer;
}
private void bfs(int[][] board, int r, int c, int[] arr) {
Queue<Point> queue = new LinkedList<>();
queue.add(new Point(r, c, 0));
boolean[][] isVisited = new boolean[4][4];
isVisited[r][c] = true;
boolean[][] enterVisited = new boolean[4][4];
int answerCnt = 0;
int idx = 0;
boolean isSecond = false;
while(!queue.isEmpty()) {
Point cur = queue.poll();
// ์นด๋ ์ผ์น
if(board[cur.x][cur.y] == arr[idx] && !enterVisited[cur.x][cur.y]) {
enterVisited[cur.x][cur.y] = true;
answerCnt++; // enter
answerCnt += cur.d; // ์ต๋จ ์ด๋ ๊ฑฐ๋ฆฌ
queue.clear();
queue.add(new Point(cur.x, cur.y, 0));
isVisited = new boolean[4][4];
isVisited[cur.x][cur.y] = true;
if(!isSecond) {
isSecond = true;
} else {
isSecond = false;
idx++;
if(idx >= arr.length) {
answer = Math.min(answer, answerCnt);
return;
}
}
continue;
}
for(int i = 0; i < 4; i++) {
int nx = cur.x + dx[i];
int ny = cur.y + dy[i];
// ํ ์นธ ์ด๋
if(0 <= nx && nx < 4 && 0 <= ny && ny < 4 && !isVisited[nx][ny]) {
isVisited[nx][ny] = true;
queue.add(new Point(nx, ny, cur.d + 1));
}
// ํ ์นธ ์ด๋ํ๊ธฐ ์ ์์น๋ก ๋ค์ ์ด๊ธฐํ
nx -= dx[i];
ny -= dy[i];
// ctrl ์ด์ฉํด์ ๋๊น์ง ์ด๋
while(0 <= nx + dx[i] && nx + dx[i] < 4 && 0 <= ny + dy[i] && ny + dy[i] < 4) {
nx += dx[i];
ny += dy[i];
// ์ค๊ฐ์ enter ํ์ง ์์ ์นด๋๊ฐ ์๋ค๋ฉด ๋ฉ์ถค
if(board[nx][ny] != 0 && !enterVisited[nx][ny]) {
break;
}
}
// ctrl ์ด๋
if(0 <= nx && nx < 4 && 0 <= ny && ny < 4 && !isVisited[nx][ny]) {
isVisited[nx][ny] = true;
queue.add(new Point(nx, ny, cur.d + 1));
}
}
}
}
private void permutation(int cnt, int[] arr, int[][] board, int r, int c) {
if(size == cnt) { // arr ์์๋๋ก bfs ๋๋ฆฌ๊ธฐ
bfs(board, r, c, arr);
return;
}
for(int i = 1; i <= 6; i++) {
if(visited[i] || !isNum[i]) { // ์๋ ์นด๋์ด๊ฑฐ๋ ๋ฐฉ๋ฌธํ์ผ๋ฉด pass
continue;
}
visited[i] = true;
arr[cnt] = i;
permutation(cnt + 1, arr, board, r, c);
visited[i] = false;
}
}
}
โจ ํฌ์คํ ์ ๋ง์น๋ฉฐ
๋๋ฌด๋๋ฌด ์ด๋ ต๊ณ ์ดํดํ๋๋ฐ๋ ๊ธด ์๊ฐ์ด ๊ฑธ๋ ธ์ง๋ง, ์๋ก์ด ํ์ด ๋ฐฉ๋ฒ์ ํ ๋ฒ์ ์๊ฒ ๋์ ์ข์๋ค. ๐