[백준] 15686번 치킨배달 - Java/자바
문제
입력
첫째 줄에 N(2 ≤ N ≤ 50)과 M(1 ≤ M ≤ 13)이 주어진다.
둘째 줄부터 N개의 줄에는 도시의 정보가 주어진다.
도시의 정보는 0, 1, 2로 이루어져 있고, 0은 빈 칸, 1은 집, 2는 치킨집을 의미한다. 집의 개수는 2N개를 넘지 않으며, 적어도 1개는 존재한다. 치킨집의 개수는 M보다 크거나 같고, 13보다 작거나 같다.
출력
- 첫째 줄에 폐업시키지 않을 치킨집을 최대 M개를 골랐을 때, 도시의 치킨 거리의 최솟값을 출력한다.
접근방법
백트래킹을 이용해서 탐색해야 하는 문제이다.-
전체 치킨집의 수(count)와 M을 이용해 폐업해야 하는 치킨집의 수(close)를 알아내고,
-
재귀를 통해 전체 치킨집들이 close수만큼 폐업하는 모든 경우의 수를 찾아주었다.
-
각 경우의 수에서 distance함수를 호출해서 모든 집들의 치킨거리를 구하는 방법을 반복해 최솟값을 반환했다.
풀이
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
class Coo {
int x, y;
Coo(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Main {
static int N, M;
static int[][] map;
static int count= 0, close;
static int countHome = 0;
static Coo[] chickens, homes;
static int min = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException {
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];
chickens = new Coo[13];
homes = new Coo[N*2];
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());
}
}
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
if(map[i][j] == 2) {
chickens[count] = new Coo(i, j);
count++;
}
else if(map[i][j] == 1) {
homes[countHome] = new Coo(i, j);
countHome++;
}
}
}
close = count - M;
dfs(0, 0);
System.out.println(min);
}
public static void dfs(int index, int depth) {
if(depth == close) {
int sum = 0;
for(int i = 0; i < countHome; i++) {
sum += distance(homes[i].x, homes[i].y);
}
min = Math.min(sum, min);
return;
}
for(int i = index; i < count; i++) {
map[chickens[i].x][chickens[i].y] = 0;
dfs(i+1, depth+1);
map[chickens[i].x][chickens[i].y] = 2;
}
}
public static int distance(int x, int y) {
int md = Integer.MAX_VALUE;
for(int i = 0; i < count; i++) {
int cx = chickens[i].x;
int cy = chickens[i].y;
if(map[cx][cy] == 2) {
int distance = Math.abs(x-cx) + Math.abs(y-cy);
md = Math.min(distance, md);
}
}
return md;
}
}
댓글남기기