[백준] 15686 치킨배달
삼성 역태 준비중!
여러개의 치킨 집 중 m개만을 살아남긴 채 치킨거리의 합을 구해야 하므로
조합이구만! 그럼 다음순열 함수를 써야겠군! 하면서 풀었던 문제…
import java.util.*;
import java.io.*;
public class Main{
// 다음 순열을 만들어주는 함수
public static boolean next_perm(int[] arr){
int i = arr.length -1;
while( i > 0 && arr[i-1] <= arr[i]){
i--;
}
if(i <= 0){
return false;
}
int j = arr.length -1;
while( arr[j] >= arr[i-1] ){
j--;
}
int temp = arr[j];
arr[j] = arr[i-1];
arr[i-1] = temp;
int k = arr.length -1;
while( i < k ){
temp = arr[k];
arr[k] = arr[i];
arr[i] = temp;
i++;
k--;
}
return true;
}
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];
int[][] shop = new int[13][2]; // 치킨집의 x, y좌표를 담을 배열
int sidx = 0; // 치킨집의 갯수
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] == 2){ // 치킨집이면 따로 저장
shop[sidx][0] = i;
shop[sidx++][1] = j;
}
}
}
int[] sel = new int[sidx]; // 조합! sdix C m 을 수행해준다
for(int i = 0 ; i < m ; i++){ // 초기 수열
sel[i] = 1;
}
int tot = 2000000000; // 치킨거리의 합의 최솟값을 담을 변수
do{
int sum = 0; // 치킨거리 합 값을 담을 변수
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < n ; j++){
if(map[i][j] == 1){ // 주택 발견!
int min = 200; // 치킨거리를 담을 변수
for(int k = 0 ; k < sidx ; k++){ // 모든 치킨집에 대해서..
if(sel[k] == 1){ // 모든 치킨집 중 살아남을 치킨집에 대해서..
int r = shop[k][0];
int c = shop[k][1];
int d = Math.abs(i-r) + Math.abs(j-c); //문제에 나와있는 공식 그대로 사용
if( d < min ){ // 가장 가까운 치킨집과의 거리만 min에 저장한다
min = d;
}
}
}
sum += min; // 치킨거리의 합에 더해준다
}
}
}
if(sum < tot ){ // 치킨 거리의 합의 최솟값이라면 tot에 저장
tot = sum;
}
}while(next_perm(sel)); // 다음 순열 만들기
System.out.println(tot);
}
}
Comments