본문 바로가기
JAVA 알고리즘

백준 15686번 - 치킨 배달

by 잡다한 저장소 2019. 11. 3.

https://www.acmicpc.net/problem/15686

 

15686번: 치킨 배달

크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸, 왼쪽에서부터 c번째 칸을 의미한다. r과 c는 1부터 시작한다. 이 도시에 사는 사람들은 치킨을 매우 좋아한다. 따라서, 사람들은 "치킨 거리"라는 말을 주로 사용한다. 치킨 거리는 집과 가장 가까운 치킨집 사이의 거리이다. 즉, 치킨 거리는

www.acmicpc.net

문제 풀이

1. 최대 M 개이므로 살아남는 치킨 집이 한 점포부터 M개의 점포까지 모든 경우의 수가 생긴다. 따라서 이 경우들을 모두 따져주어야 도시의 치킨 거리의 최소값을 계산할 수 있을 것이다.

 따라서 K개의 치킨 집이 있다면 그 중, 1~M개의 치킨 집을 선택하여야 한다. 앞서 비트 마스크에 대한 글을 올렸으므로, 이번 문제도 비트 마스크를 이용하여 풀어보았다. 살짝 다른 점이 있다면 1~M개를 선택해야 하므로 0을 걸러주어야 한다.

 

2. 처음엔 치킨 집을 우선시 하여 치킨 집의 반복문을 앞서 작성하였는데 이렇게 작성시 일반 집의 반복문이 안으로 들어가 살아있는 모든 치킨 집에 대한 각 일반 집의 치킨 거리의 최소값을 저장해두기가 애매해진다. 배열을 사용할 수도 있지만 일반 집의 반복문을 앞서 작성하면, 한 집에 대해서 다음번 치킨 집 반복문에서 모든 치킨 거리를 구할 수 있기 때문에 이경우가 좀 더 효율적이다.

 

3. 위에서 구한 각 집의 치킨 거리의 최소값을 모두 더하여 이를 최종 변수와 비교하면서 최소값을 도출해낸다.

 

 

import java.util.ArrayList;
import java.util.Scanner;

class Pair {
    int x; 
    int y;
    Pair(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
public class BOJ15686 {
    static int n;
    static int m;
    static int[][] inputAry;
    static ArrayList<Pair> storeList;
    static ArrayList<Pair> personList;
    static int answer = Integer.MAX_VALUE;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();
        inputAry = new int[n][n];
        storeList = new ArrayList<Pair>();
        personList = new ArrayList<Pair>();
        ArrayList<Pair> answerList = new ArrayList<Pair>();
	    
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                inputAry[i][j] = sc.nextInt();
                if(inputAry[i][j] == 2) {
                    storeList.add(new Pair(i,j));
                } else if(inputAry[i][j] == 1) {
                    personList.add(new Pair(i,j));
                }
            }
        }
        System.out.println(storeList.size());
        boolean[] check = new boolean[storeList.size()];
	    
        dfs(0,0, answerList, check);
        System.out.println(answer);
    }
    public static void dfs(int start, int depth, ArrayList<Pair> answerList, boolean[] check) {
        if(depth == m) {
            int sum = calAnswer(answerList);
            answer = Math.min(answer, sum);
            return;
        }
        for(int i = start; i < storeList.size(); i++) {
            if(check[i])
                continue;
            check[i] = true;
            answerList.add(storeList.get(i));
            dfs(i+1, depth+1, answerList, check);
            answerList.remove(answerList.size()-1);
            check[i] = false;
        }
    }
	public static int calAnswer(ArrayList<Pair> answerList) {
        int sum = 0;
        for(int i = 0; i < personList.size(); i++) {
            Pair p1 = personList.get(i);
            int len = Integer.MAX_VALUE;
            for(int j = 0; j < answerList.size(); j++) {
                Pair p2 = answerList.get(j);
                int temp = Math.abs(p1.x-p2.x) + Math.abs(p1.y-p2.y);
                len = Math.min(len, temp);
            }
            sum += len;
        }
        return sum;
    }
}

'JAVA 알고리즘 ' 카테고리의 다른 글

SWEA 1859 백만 장자 프로젝트  (1) 2020.01.13
백준 6588번 - 골드바흐의 추측  (0) 2019.11.03
백준 2661번 - 좋은수열  (0) 2019.11.02
백준 6603번 로또  (0) 2019.11.01
백준 11651번 - 좌표정렬하기2  (0) 2019.10.29