[Algorithm] 치킨 배달.java 15686 조합

Jifrozen·2021년 10월 7일
0

Algorithm

목록 보기
55/70

치킨 배달

import java.util.*;
import java.io.*;

//치킨집 고르기 (조합)
class Combination {
    private int n;// 치킨집 전체 개수
    private int r;// 뽑을 개수
    private int[] now; // 현재 조합
    private ArrayList<ArrayList<Position>> result; // 모든 조합

    public ArrayList<ArrayList<Position>> getResult() {
        return result;
    }

    public Combination(int n, int r) {
        this.n = n;
        this.r = r;
        this.now = new int[r];
        this.result = new ArrayList<ArrayList<Position>>();
    }

    public void combination(ArrayList<Position> arr, int depth, int index, int target) {
        if (depth == r) {
            ArrayList<Position> temp = new ArrayList<>();
            for (int i = 0; i < now.length; i++) {
                temp.add(arr.get(now[i]));
            }
            result.add(temp);
            return;
        }
        if (target == n)
            return;
        now[index] = target;
        combination(arr, depth + 1, index + 1, target + 1);
        combination(arr, depth, index, target + 1);
    }
}

class Position {
    private int x;
    private int y;

    public Position(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return this.x;
    }

    public int getY() {
        return this.y;
    }
}

public class 치킨배달 {

    public static int n, m;
    public static int[][] arr = new int[50][50];
    public static ArrayList<Position> chicken = new ArrayList<>();
    public static ArrayList<Position> house = new ArrayList<>();

    public static int getSum(ArrayList<Position> candidates) {
        int result = 0;
        // 모든 집에 대하여
        for (int i = 0; i < house.size(); i++) {
            int hx = house.get(i).getX();
            int hy = house.get(i).getY();
            // 가장 가까운 치킨 집을 찾기
            int temp = (int) 1e9;
            for (int j = 0; j < candidates.size(); j++) {
                int cx = candidates.get(j).getX();
                int cy = candidates.get(j).getY();
                temp = Math.min(temp, Math.abs(hx - cx) + Math.abs(hy - cy));
            }
            // 가장 가까운 치킨 집까지의 거리를 더하기
            result += temp;
        }
        // 치킨 거리의 합 반환
        return result;
    }

    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());

        for (int r = 0; r < n; r++) {
            st = new StringTokenizer(br.readLine());
            for (int c = 0; c < n; c++) {
                arr[r][c] = Integer.parseInt(st.nextToken());
                if (arr[r][c] == 1)
                    house.add(new Position(r, c)); // 일반 집
                else if (arr[r][c] == 2)
                    chicken.add(new Position(r, c)); // 치킨집
            }
        }

        // 모든 치킨 집 중에서 m개의 치킨 집을 뽑는 조합 계산
        Combination comb = new Combination(chicken.size(), m);
        comb.combination(chicken, 0, 0, 0);
        ArrayList<ArrayList<Position>> chickenList = comb.getResult();

        // 치킨 거리의 합의 최소를 찾아 출력
        int result = (int) 1e9;
        for (int i = 0; i < chickenList.size(); i++) {
            result = Math.min(result, getSum(chickenList.get(i)));
        }
        System.out.println(result);
    }
}

폐업할 치킨집 제외 모든 치킨집에서 집까지 최소 거리구하는 문제

1. 치킨집 조합 구하기

파이썬은 combination 써서 풀었는데 자바 구려

    public void combination(ArrayList<Position> arr, int depth, int index, int target) {// arr 은 치킨 좌표값, depth는 조합 몇개인지 index 는 현재 조합의 index를 유지하기 위해 target은 조합에서 차례로 넘어가는 
        if (depth == r) { // 조합 개수 다 맞춰진 경우
            ArrayList<Position> temp = new ArrayList<>();// 임시 보관
            for (int i = 0; i < now.length; i++) {
                temp.add(arr.get(now[i]));
            }
            result.add(temp);
            return;
        }
        if (target == n)// 끝까지 간 경우 경우를 다 돌아봄
            return;
        now[index] = target;//target을 index에 집어넣음
        combination(arr, depth + 1, index + 1, target + 1);// 뽑는 경우
        combination(arr, depth, index, target + 1); // 안뽑는 경우
    }
}

(2,3) 뽑는다면 now[0]=0
(3,3) 뽑는다면 now[1]=1

depth=2이므로 종료
temp에 chicken(0) chicken(1) -> result
이런식으로 반복된다.

2. 모든 조합에서 집까지 거리 최소값 구한다

    public static int getSum(ArrayList<Position> candidates) {
        int result = 0;
        // 모든 집에 대하여
        for (int i = 0; i < house.size(); i++) {
            int hx = house.get(i).getX();
            int hy = house.get(i).getY();
            // 가장 가까운 치킨 집을 찾기
            int temp = (int) 1e9;
            for (int j = 0; j < candidates.size(); j++) {
                int cx = candidates.get(j).getX();
                int cy = candidates.get(j).getY();
                temp = Math.min(temp, Math.abs(hx - cx) + Math.abs(hy - cy));
            }
            // 가장 가까운 치킨 집까지의 거리를 더하기
            result += temp;
        }
        // 치킨 거리의 합 반환
        return result;
    }

0개의 댓글