Skip to content

Commit 095c190

Browse files
committed
[Gold V] Title: 치킨 배달, Time: 192 ms, Memory: 12444 KB -BaekjoonHub
1 parent e8082c1 commit 095c190

2 files changed

Lines changed: 123 additions & 0 deletions

File tree

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# [Gold V] 치킨 배달 - 15686
2+
3+
[문제 링크](https://www.acmicpc.net/problem/15686)
4+
5+
### 성능 요약
6+
7+
메모리: 12444 KB, 시간: 192 ms
8+
9+
### 분류
10+
11+
백트래킹, 브루트포스 알고리즘, 구현
12+
13+
### 제출 일자
14+
15+
2025년 2월 26일 18:20:58
16+
17+
### 문제 설명
18+
19+
<p>크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸, 왼쪽에서부터 c번째 칸을 의미한다. r과 c는 1부터 시작한다.</p>
20+
21+
<p>이 도시에 사는 사람들은 치킨을 매우 좋아한다. 따라서, 사람들은 "<strong>치킨 거리</strong>"라는 말을 주로 사용한다. <strong>치킨 거리</strong>는 집과 가장 가까운 치킨집 사이의 거리이다. 즉, 치킨 거리는 집을 기준으로 정해지며, 각각의 집은 <strong>치킨 거리</strong>를 가지고 있다. <strong>도시의 치킨 거리</strong>는 모든 집의 <strong>치킨 거리</strong>의 합이다.</p>
22+
23+
<p>임의의 두 칸 (r<sub>1</sub>, c<sub>1</sub>)과 (r<sub>2</sub>, c<sub>2</sub>) 사이의 거리는 |r<sub>1</sub>-r<sub>2</sub>| + |c<sub>1</sub>-c<sub>2</sub>|로 구한다.</p>
24+
25+
<p>예를 들어, 아래와 같은 지도를 갖는 도시를 살펴보자.</p>
26+
27+
<pre>0 2 0 1 0
28+
1 0 1 0 0
29+
0 0 0 0 0
30+
0 0 0 1 1
31+
0 0 0 1 2
32+
</pre>
33+
34+
<p>0은 빈 칸, 1은 집, 2는 치킨집이다.</p>
35+
36+
<p>(2, 1)에 있는 집과 (1, 2)에 있는 치킨집과의 거리는 |2-1| + |1-2| = 2, (5, 5)에 있는 치킨집과의 거리는 |2-5| + |1-5| = 7이다. 따라서, (2, 1)에 있는 집의 치킨 거리는 2이다.</p>
37+
38+
<p>(5, 4)에 있는 집과 (1, 2)에 있는 치킨집과의 거리는 |5-1| + |4-2| = 6, (5, 5)에 있는 치킨집과의 거리는 |5-5| + |4-5| = 1이다. 따라서, (5, 4)에 있는 집의 치킨 거리는 1이다.</p>
39+
40+
<p>이 도시에 있는 치킨집은 모두 같은 프랜차이즈이다. 프렌차이즈 본사에서는 수익을 증가시키기 위해 일부 치킨집을 폐업시키려고 한다. 오랜 연구 끝에 이 도시에서 가장 수익을 많이 낼 수 있는 치킨집의 개수는 최대 M개라는 사실을 알아내었다.</p>
41+
42+
<p>도시에 있는 치킨집 중에서 최대 M개를 고르고, 나머지 치킨집은 모두 폐업시켜야 한다. 어떻게 고르면, <strong>도시의 치킨 거리</strong>가 가장 작게 될지 구하는 프로그램을 작성하시오.</p>
43+
44+
### 입력
45+
46+
<p>첫째 줄에 N(2 ≤ N ≤ 50)과 M(1 ≤ M ≤ 13)이 주어진다.</p>
47+
48+
<p>둘째 줄부터 N개의 줄에는 도시의 정보가 주어진다.</p>
49+
50+
<p>도시의 정보는 0, 1, 2로 이루어져 있고, 0은 빈 칸, 1은 집, 2는 치킨집을 의미한다. 집의 개수는 2N개를 넘지 않으며, 적어도 1개는 존재한다. 치킨집의 개수는 M보다 크거나 같고, 13보다 작거나 같다.</p>
51+
52+
### 출력
53+
54+
<p>첫째 줄에 폐업시키지 않을 치킨집을 최대 M개를 골랐을 때, 도시의 치킨 거리의 최솟값을 출력한다.</p>
55+
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// N
2+
let fs = require('fs');
3+
let input = fs.readFileSync('/dev/stdin').toString().split('\n');
4+
5+
let [N, M] = input[0].split(' ').map(Number);
6+
7+
let houseArr = [];
8+
let chickenArr = [];
9+
10+
// 집, 치킨집 좌표 저장
11+
for (let i = 0; i < N; i++) {
12+
let row = input[i + 1].split(' ').map(Number);
13+
14+
for (let j = 0; j < N; j++) {
15+
if (row[j] === 1) houseArr.push([i, j]);
16+
if (row[j] === 2) chickenArr.push([i, j]);
17+
}
18+
}
19+
20+
let selected = [];
21+
let answer = Infinity;
22+
23+
// 치킨 거리 계산
24+
const getChickenDistance = () => {
25+
let totalDist = 0;
26+
27+
for (let [hx, hy] of houseArr) {
28+
let minDist = Infinity;
29+
30+
for (let idx of selected) {
31+
let [cx, cy] = chickenArr[idx];
32+
let distance = Math.abs(hx - cx) + Math.abs(hy - cy);
33+
minDist = Math.min(minDist, distance);
34+
}
35+
36+
totalDist += minDist;
37+
}
38+
39+
return totalDist;
40+
};
41+
42+
// DFS로 치킨집 경우의 수 다 돌기
43+
const dfs = (depth, start) => {
44+
if (depth === M) {
45+
answer = Math.min(answer, getChickenDistance());
46+
return;
47+
}
48+
49+
for (let i = start; i < chickenArr.length; i++) {
50+
selected.push(i);
51+
dfs(depth + 1, i + 1);
52+
selected.pop();
53+
}
54+
};
55+
56+
dfs(0, 0);
57+
58+
console.log(answer);
59+
60+
// 폐업을 모든 경우의 수로 하며 각 집에서 모든 치킨집에 대한 거리를 계산해서 최소값을 저장 => 집을 찾을 때 N * 모든 치킨집 거리 계산 N (N이 최대 50이라 괜찮음)
61+
// 1번 최소값을 찾아 더한다
62+
// 폐업에 대해서 visited 처리를 하면 어떨까
63+
// dfs에 장사를 하는 치킨집 개수를 넘기도록 한다.
64+
// 치킨집 개수가 차면 그 상황에 대해서 계산을 진행하고
65+
66+
// 50m
67+
// 막혔던 부분: 모든 인덱스를 확인해야 하는데 이건 어떻게 구현하지? => 모든 인덱스에 대해 실행하고 DFS에 index 값을 같이 넘겨주면 됨, 집 배열과 치킨집 배열을 관리
68+
// 현재 선택된 치킨집 배열도 관리해야 함

0 commit comments

Comments
 (0)