Algorithm
[백준 - JAVA] 치킨 배달
메징징
2020. 12. 9. 17:37
반응형
15686번: 치킨 배달
크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸
www.acmicpc.net
문제를 풀기 시작하자마자 치킨이 먹고 싶어져서,
스터디원들과 30분만에 풀고 다같이 치맥을 먹으러 갔던 문제 ◝(⁰▿⁰)◜
M이 13이하의 수이기 때문에 기초적인 조합을 구현할 수 있다면 풀 수 있다!
풀이 방법
-
입력을 받으면서, 치킨집과 집의 좌표를 리스트에 각각 저장한다.
- 치킨집의 리스트로 dfs를 이용한 조합을 구현한다.
- boolean형 배열을 이용해서 중복 처리를 한다.
- 치킨집을 M개 골랐을 때 도시의 치킨거리를 구한다.
M개의 치킨집 중 각각의 집에서 가장 가까운 거리를 구해 합한 다음,
기존까지 구한 도시의 치킨거리와 비교하여 더 작은 값을 저장한다.
import java.io.*;
import java.util.*;
public class Main {
public static int[][] map;
public static int N, M, min;
public static List<int[]> chicken, house, mList;
public static boolean[] v;
public static void pick(int index, int cnt) {
if (cnt == M) {
int sum = 0;
for (int[] h : house) {
int dis = Integer.MAX_VALUE;
for (int[] arr : mList) {
dis = Math.min(dis, Math.abs(arr[0]-h[0])+Math.abs(arr[1]-h[1]));
}
sum+=dis;
if (sum > min)
return;
}
min = Math.min(min, sum);
return;
}
for (int i = index; i < chicken.size(); i++) {
if (!v[i]) {
v[i] = true;
mList.add(chicken.get(i));
pick(i + 1, cnt + 1);
mList.remove(cnt);
v[i] = false;
}
}
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
map = new int[N][N];
chicken = new ArrayList<int[]>();
house = new ArrayList<int[]>();
mList = new ArrayList<int[]>();
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
if (map[i][j] == 1)
house.add(new int[] { i, j });
else if (map[i][j] == 2)
chicken.add(new int[] { i, j });
}
}
min = Integer.MAX_VALUE;
v = new boolean[chicken.size()];
pick(0, 0);
System.out.println(min);
}
}