공부/코테 풀이
백준 15686 치킨 배달 - 조합, 백트레킹
확두뇌
2024. 2. 7. 16:47
이 문제는 백트레킹을 이용해 조합을 구현하고 차근히 조건을 생각하며 풀면 풀리는 문제다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.StringTokenizer;
public class Main {
//조합 구현 코드
public static ArrayList<ArrayList<int[]>> combination(ArrayList<int[]> storeList, int m){
ArrayList<ArrayList<int[]>> ans = new ArrayList<ArrayList<int[]>>();
ArrayList<int[]> curr = new ArrayList<int[]>();
boolean[] used = new boolean[storeList.size()];
int start = 0;
backtrack(start, storeList, m, ans, curr, used);
return ans;
}
//조합 구현 코드
public static void backtrack(int start, ArrayList<int[]> storeList, int m, ArrayList<ArrayList<int[]>> ans, ArrayList<int[]> curr, boolean[] used) {
if(curr.size() == m) {
ans.add(new ArrayList<int[]>(curr));
return;
}
for(int i=start; i < storeList.size(); i++) {
if(!used[i]) {
used[i] = true;
curr.add(storeList.get(i));
backtrack(i+1, storeList, m, ans, curr, used);
used[i] = false;
curr.remove(curr.size()-1);
}
}
}
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int[][] map = new int[n][n];
ArrayList<int[]> storeList = new ArrayList<int[]>();
ArrayList<int[]> home = new ArrayList<int[]>();
for(int i=0; i<n; i++) {
st = new StringTokenizer(br.readLine());
for(int j=0; j<n; j++) {
int num = Integer.parseInt(st.nextToken());
map[i][j] = num;
if(num == 2) {
//치킨집
storeList.add(new int[] {i,j});
}else if(num == 1) {
//집
home.add(new int[] {i,j});
}
}
}
//가능한 모든 치킨집 조합
ArrayList<ArrayList<int[]>> c = combination(storeList, m);
int[] minList = new int[c.size()]; //치킨집 선택한 모든 경우의 별 도시치킨거리 담은 배열
for(int i=0; i<c.size(); i++) {
//선택한 치킨집의 경우의 수 별 도시치킨거리 모두 계산하기
//c의 최대 크기는 10의 3승
for(int h=0; h<home.size(); h++) {
int home_x = home.get(h)[0];
int home_y = home.get(h)[1];
ArrayList<Integer> compare = new ArrayList<Integer>();
for(int j=0; j<m; j++) {
int x = c.get(i).get(j)[0]; //치킨집 x 좌표
int y = c.get(i).get(j)[1]; //치킨집 y 좌표
int value = Math.abs(x-home_x)+Math.abs(y-home_y);
compare.add(value);
}
Collections.sort(compare);
//minList 값 하나씩 채우기
minList[i] += compare.get(0);
}
}
//제일 작은거 뽑기 위해 정렬
Arrays.sort(minList);
System.out.println(minList[0]);
}
}