(Java) 백준 15686 - 치킨 배달

2022. 7. 15. 03:03·코딩 테스트

예전에 풀었던 프로그래머스 거리두기 확인하기와 비슷하다고 느낀 문제였다.
이번 문제는 탐색보다 구현에 더 초점이 맞춰져 있던 것 같다.
요즘 코테를 보면서 느낀 코테 트렌트는 구현인 것 같다.
특정한 알고리즘을 알아야 풀 수 있는 문제도 몇 문제 있었지만 대부분이 구현 문제였다.
그래서 구현 문제를 중심으로 연습해야 할 것 같다.

문제를 읽고 이렇게 나누어 로직을 짰다.
1. 치킨 집중에서 m개를 선택해 조합 구하기
2. 구한 조합으로 각 집마다 치킨 거리 구하여 최솟값을 선택
3. 각 집에 최솟값을 더하여 도시의 치킨 거리 구하기
4. 모든 조합을 돌면서 도시의 치킨 거리의 최솟값을 반환

다만 이 로직이 맞는지 확신이 들지 않았지만 떠오르는 게 이 방법밖에 없어 코드로 구현했다.
구현하며 몇 번 막혔던 적이 있는데 처음에는 치킨집과 집을 Map에 넣었었다. Map에 KeySet을 통해서
좌표를 구하려고 했는데 Set을 하나씩 꺼내는 게 쉽지 않았다.
또, 치킨집들의 조합을 구하는 게 묘하게 어려워서 시간이 많이 걸렸다.
순열, 조합, 중복 조합은 자유롭게 쓸 수 있게 연습해야 할 것 같다.


최종 코드

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class Main {
    static int n, m, min;
    static int[] com;
    static ArrayList<int[]> chickenList;
    static ArrayList<int[]> homeList;

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

        int[][] arr = new int[n][n];
        chickenList = new ArrayList<>();
        homeList = new ArrayList<>();
        // 조합을 저장할 배열
        com = new int[m];
        min = Integer.MAX_VALUE;

        // 입력값 배열 삽입 및 list에 치킨집과 집 삽입
        for (int i = 0; i < n; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < n; j++) {
                arr[i][j] = Integer.parseInt(st.nextToken());
                if (arr[i][j] == 2) {
                    chickenList.add(new int[]{i, j});
                } else if (arr[i][j] == 1) {
                    homeList.add(new int[]{i, j});
                }
            }
        }
        combination(0, 0);
        System.out.println(min);
    }

    // 조합을 구하는 메서드
    static void combination(int idx, int depth) {
        // 조합이 하나 만들어지면 도시 치킨거리 구하기
        if (depth == m) {
            min = Math.min(minLength(), min);
            return;
        }
        for (int i = idx; i < chickenList.size(); i++) {
            com[depth] = i;
            combination(i + 1, depth + 1);
        }
    }

    // 조합에서 치킨거리 구하기
    static int minLength() {
        int sum = 0;
        for (int[] homeTemp : homeList) {
            int chickenLength = Integer.MAX_VALUE;
            int hx = homeTemp[0];
            int hy = homeTemp[1];

            for (int i = 0; i < com.length; i++) {
                int[] chickenTemp = chickenList.get(com[i]);
                int cx = chickenTemp[0];
                int cy = chickenTemp[1];

                // 각 집의 치킨거리
                chickenLength = Math.min(Math.abs(hx - cx) + Math.abs(hy - cy), chickenLength);
            }
            // 현재 조합에서 도시 치킨거리
            sum += chickenLength;
        }
        return sum;
    }
}

'코딩 테스트' 카테고리의 다른 글

(Java) 백준 2447 - 별 찍기 10  (0) 2022.07.16
(Java) 프로그래머스 - 순위 검색  (0) 2022.07.16
(Java) 프로그래머스 - 멀쩡한 사각형  (0) 2022.07.14
(Java) 프로그래머스 - 게임 맵 최단거리  (0) 2022.07.12
(Java) 백준 12865 - 평범한 배낭  (0) 2022.07.12
'코딩 테스트' 카테고리의 다른 글
  • (Java) 백준 2447 - 별 찍기 10
  • (Java) 프로그래머스 - 순위 검색
  • (Java) 프로그래머스 - 멀쩡한 사각형
  • (Java) 프로그래머스 - 게임 맵 최단거리
로승리
로승리
  • 로승리
    Roy's Blog
    로승리
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Issuefy
      • Language
      • Spring
      • Database
      • Network
      • Kubernetes
      • AWS
      • 코드스쿼드
      • 코딩 테스트
      • 생각정리
      • 국비지원
      • 회고
      • 컨퍼런스, 세미나
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
로승리
(Java) 백준 15686 - 치킨 배달
상단으로

티스토리툴바