Skip to content

Commit 8bde42e

Browse files
committed
[level 3] Title: [카카오 인턴] 경주로 건설, Time: 37.85 ms, Memory: 39 MB -BaekjoonHub
1 parent 684e388 commit 8bde42e

2 files changed

Lines changed: 189 additions & 0 deletions

File tree

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# [level 3] [카카오 인턴] 경주로 건설 - 67259
2+
3+
[문제 링크](https://school.programmers.co.kr/learn/courses/30/lessons/67259)
4+
5+
### 성능 요약
6+
7+
메모리: 39 MB, 시간: 37.85 ms
8+
9+
### 구분
10+
11+
코딩테스트 연습 > 2020 카카오 인턴십
12+
13+
### 채점결과
14+
15+
정확성: 100.0<br/>합계: 100.0 / 100.0
16+
17+
### 제출 일자
18+
19+
2026년 04월 23일 15:20:32
20+
21+
### 문제 설명
22+
23+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/384b9e2a-4eb5-460d-bce2-d12359b03b14/kakao_road1.png" title="" alt="kakao_road1.png"></p>
24+
25+
<p>건설회사의 설계사인 <code>죠르디</code>는 고객사로부터 자동차 경주로 건설에 필요한 견적을 의뢰받았습니다.<br>
26+
제공된 경주로 설계 도면에 따르면 경주로 부지는 <code>N x N</code> 크기의 정사각형 격자 형태이며 각 격자는 <code>1 x 1</code> 크기입니다.<br>
27+
설계 도면에는 각 격자의 칸은 <code>0</code> 또는 <code>1</code> 로 채워져 있으며, <code>0</code>은 칸이 비어 있음을 <code>1</code>은 해당 칸이 벽으로 채워져 있음을 나타냅니다.<br>
28+
경주로의 출발점은 (0, 0) 칸(좌측 상단)이며, 도착점은 (N-1, N-1) 칸(우측 하단)입니다. 죠르디는 출발점인 (0, 0) 칸에서 출발한 자동차가 도착점인 (N-1, N-1) 칸까지 무사히 도달할 수 있게 중간에 끊기지 않도록 경주로를 건설해야 합니다.<br>
29+
경주로는 상, 하, 좌, 우로 인접한 두 빈 칸을 연결하여 건설할 수 있으며, 벽이 있는 칸에는 경주로를 건설할 수 없습니다.<br>
30+
이때, 인접한 두 빈 칸을 상하 또는 좌우로 연결한 경주로를 <code>직선 도로</code> 라고 합니다.<br>
31+
또한 두 <code>직선 도로</code>가 서로 직각으로 만나는 지점을 <code>코너</code> 라고 부릅니다.<br>
32+
건설 비용을 계산해 보니 <code>직선 도로</code> 하나를 만들 때는 100원이 소요되며, <code>코너</code>를 하나 만들 때는 500원이 추가로 듭니다.<br>
33+
죠르디는 견적서 작성을 위해 경주로를 건설하는 데 필요한 최소 비용을 계산해야 합니다.</p>
34+
35+
<p>예를 들어, 아래 그림은 <code>직선 도로</code> 6개와 <code>코너</code> 4개로 구성된 임의의 경주로 예시이며, 건설 비용은 6 x 100 + 4 x 500 = 2600원 입니다.</p>
36+
37+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/0e0911e8-f88e-44fe-8bdc-6856a56df8e0/kakao_road2.png" title="" alt="kakao_road2.png"></p>
38+
39+
<p>또 다른 예로, 아래 그림은 <code>직선 도로</code> 4개와 <code>코너</code> 1개로 구성된 경주로이며, 건설 비용은 4 x 100 + 1 x 500 = 900원 입니다.</p>
40+
41+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/3f5d9c5e-d7d9-4248-b111-140a0847e741/kakao_road3.png" title="" alt="kakao_road3.png"></p>
42+
43+
<hr>
44+
45+
<p>도면의 상태(0은 비어 있음, 1은 벽)을 나타내는 2차원 배열 board가 매개변수로 주어질 때, 경주로를 건설하는데 필요한 최소 비용을 return 하도록 solution 함수를 완성해주세요.</p>
46+
47+
<h5><strong>[제한사항]</strong></h5>
48+
49+
<ul>
50+
<li>board는 2차원 정사각 배열로 배열의 크기는 3 이상 25 이하입니다.</li>
51+
<li>board 배열의 각 원소의 값은 0 또는 1 입니다.
52+
53+
<ul>
54+
<li>도면의 가장 왼쪽 상단 좌표는 (0, 0)이며, 가장 우측 하단 좌표는 (N-1, N-1) 입니다.</li>
55+
<li>원소의 값 0은 칸이 비어 있어 도로 연결이 가능함을 1은 칸이 벽으로 채워져 있어 도로 연결이 불가능함을 나타냅니다.</li>
56+
</ul></li>
57+
<li>board는 항상 출발점에서 도착점까지 경주로를 건설할 수 있는 형태로 주어집니다.</li>
58+
<li>출발점과 도착점 칸의 원소의 값은 항상 0으로 주어집니다.</li>
59+
</ul>
60+
61+
<hr>
62+
63+
<h5><strong>입출력 예</strong></h5>
64+
<table class="table">
65+
<thead><tr>
66+
<th>board</th>
67+
<th>result</th>
68+
</tr>
69+
</thead>
70+
<tbody><tr>
71+
<td>[[0,0,0],[0,0,0],[0,0,0]]</td>
72+
<td>900</td>
73+
</tr>
74+
<tr>
75+
<td>[[0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0],[0,0,0,0,0,1,0,0],[0,0,0,0,1,0,0,0],[0,0,0,1,0,0,0,1],[0,0,1,0,0,0,1,0],[0,1,0,0,0,1,0,0],[1,0,0,0,0,0,0,0]]</td>
76+
<td>3800</td>
77+
</tr>
78+
<tr>
79+
<td>[[0,0,1,0],[0,0,0,0],[0,1,0,1],[1,0,0,0]]</td>
80+
<td>2100</td>
81+
</tr>
82+
<tr>
83+
<td>[[0,0,0,0,0,0],[0,1,1,1,1,0],[0,0,1,0,0,0],[1,0,0,1,0,1],[0,1,0,0,0,1],[0,0,0,0,0,0]]</td>
84+
<td>3200</td>
85+
</tr>
86+
</tbody>
87+
</table>
88+
<h5><strong>입출력 예에 대한 설명</strong></h5>
89+
90+
<p><strong>입출력 예 #1</strong></p>
91+
92+
<p>본문의 예시와 같습니다.</p>
93+
94+
<p><strong>입출력 예 #2</strong></p>
95+
96+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/ccc72e9c-2e22-4a09-a94b-ff057b081a70/kakao_road4.png" title="" alt="kakao_road4.png"></p>
97+
98+
<p>위와 같이 경주로를 건설하면 <code>직선 도로</code> 18개, <code>코너</code> 4개로 총 3800원이 듭니다.</p>
99+
100+
<p><strong>입출력 예 #3</strong></p>
101+
102+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/422e86e0-a7d7-4a09-9b42-2b6218a9b5f0/kakao_road5.png" title="" alt="kakao_road5.png"></p>
103+
104+
<p>위와 같이 경주로를 건설하면 <code>직선 도로</code> 6개, <code>코너</code> 3개로 총 2100원이 듭니다.</p>
105+
106+
<p><strong>입출력 예 #4</strong></p>
107+
108+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/4fe42f47-2592-4cb8-91fb-31d6a6da8639/kakao_road6.png" title="" alt="kakao_road6.png"></p>
109+
110+
<p>붉은색 경로와 같이 경주로를 건설하면 <code>직선 도로</code> 12개, <code>코너</code> 4개로 총 3200원이 듭니다.<br>
111+
만약, 파란색 경로와 같이 경주로를 건설한다면 <code>직선 도로</code> 10개, <code>코너</code> 5개로 총 3500원이 들며, 더 많은 비용이 듭니다.</p>
112+
113+
<hr>
114+
115+
<p>※ 공지 - 2021년 8월 30일 테스트케이스가 추가되었습니다.</p>
116+
117+
118+
> 출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* 경주로 부지 NxN 정사각형 격자 형태
3+
* 각 격자는 1x1 크기
4+
*
5+
* 0 or 1로 채워져있고 0은 비어있음, 1은 벽으로 채워져있음을 뜻함
6+
* 경주로 출발점 (0,0), 도착점 (N-1, N-1)
7+
* 출발점에서 도착점까지 끊기지 않도록 경주로 건설해야함
8+
* 상,하,좌,우 인접한 두 빈칸을 연결해 건설 가능, 벽이 있으면 건설 불가
9+
* 두 직선도로가 서로 직각으로 만나는 지점: 코너
10+
* 건설 비용: 직선도로 하나 만들 때 100원, 코너 하나 만들 때 500원
11+
* 경주로 건설에 필요한 최소 비용 = ?
12+
*
13+
* 2차원 배열 board가 매개변수로 주어질때 경주로 건설 최소비용 return하기
14+
**/
15+
16+
function solution(board) {
17+
const queue = [];
18+
const N = board.length;
19+
20+
//방향
21+
const directions = [
22+
[-1, 0], //상
23+
[1, 0], //하
24+
[0, -1], //좌
25+
[0, 1], //우
26+
];
27+
28+
const dist = Array.from({ length: N }, () =>
29+
Array.from({ length: N }, () => Array(4).fill(Infinity))
30+
);
31+
32+
//[row, col, cost, direction]
33+
//처음 시작점 [0,0]에서의 이동 처리 => 오른쪽으로 가거나 아래로 가거나 두 경우만 있음
34+
if (board[0][1] === 0) {
35+
queue.push([0, 1, 100, 3]); //오른쪽 이동
36+
dist[0][1][3] = 100;
37+
}
38+
39+
if (board[1][0] === 0) {
40+
queue.push([1, 0, 100, 1]); //아래쪽 이동
41+
dist[1][0][1] = 100;
42+
}
43+
44+
let head = 0;
45+
while (queue.length > head) {
46+
const [r, c, currentCost, prevDir] = queue[head++];
47+
48+
for (let i = 0; i < 4; i++) {
49+
const nr = r + directions[i][0];
50+
const nc = c + directions[i][1];
51+
52+
if (nr < 0 || nr >= N || nc < 0 || nc >= N || board[nr][nc] === 1)
53+
continue;
54+
55+
const nextCost = currentCost + (prevDir === i ? 100 : 600);
56+
57+
if (nextCost < dist[nr][nc][i]) {
58+
dist[nr][nc][i] = nextCost;
59+
queue.push([nr, nc, nextCost, i]);
60+
}
61+
}
62+
}
63+
64+
let answer = Infinity;
65+
66+
for (const cost of dist[N - 1][N - 1]) {
67+
if (cost < answer) answer = cost;
68+
}
69+
70+
return answer;
71+
}

0 commit comments

Comments
 (0)