728x90
안녕하세요 Coding-Knowjam입니다.
이번에 풀어볼 문제는 백준 온라인 저지에 있는 15686번 치킨 배달입니다.
https://www.acmicpc.net/problem/15686
1. 문제 설명
문제에서 요구하는 바는 도시의 치킨 거리가 최소일 때의 값을 구하는 것입니다.
도시가 최대로 가질 수 있는 치킨집의 개수는 M으로 정해져 있으므로, 도시 전체의 치킨집 중에서 M개의 치킨집을 선택했을 때 치킨 거리가 최솟값이 되면 됩니다.
도시의 크기와 치킨집의 개수가 크지 않기 때문에 모든 경우의 수를 탐색하는 브루트 포스 알고리즘으로 접근해서 풀 수 있습니다.
경우의 수를 탐색하기 위해 저는 재귀 메서드로 구현했습니다.
한 가지 유의사항은 M개의 치킨집을 고르고 가정집에서의 치킨 거리를 구할 때, 모든 치킨집을 다 계산한 후에 가장 작은 값을 치킨 거리로 설정하는 부분을 빼먹으시면 안 된다는 점입니다.
그럼 코드로 작성해보겠습니다.
2. Java로 문제 풀이
package study.blog.codingnojam.algorithm;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class BOJ_15686 {
static int result = Integer.MAX_VALUE;
// 백준온라인저지 15686 치킨배달 문제 Java풀이
public static void main(String[] args) throws IOException {
// 입력을 받을 객체
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 도시 크기, 치킨집 개수 받기
String[] info = br.readLine().split(" ");
int N = Integer.parseInt(info[0]);
int M = Integer.parseInt(info[1]);
// 치킨집들을 저장할 리스트
List<Chicken> chickens = new ArrayList<>();
// 여러개의 치킨집 중에 M개를 뽑아낼 때 저장할 리스트
List<Chicken> search = new ArrayList<>();
// 도시를 나타낼 2차원 배열
// 0인덱스는 쓰지 않기 위해 길이 1씩 증가
int[][] city = new int[N + 1][N + 1];
// 도시를 나타내는 2차원 배열 초기화
// 0인덱스는 사용하지 않으므로 1부터 시작
for (int i = 1; i < city.length; i++) {
String[] temp = br.readLine().split(" ");
for (int j = 1; j < city[i].length; j++) {
// 초기화 과정에서 치킨집 발견 시 리스트에 저장
if (Integer.parseInt(temp[j-1]) == 2) {
chickens.add(new Chicken(i, j));
}
city[i][j] = Integer.parseInt(temp[j-1]);
}
}
// 재귀메서드로 모든 경우의수 체크 시작
recursion(city, 0, M, chickens, search);
// 결과 출력
System.out.println(result);
}
// 치킨집
static class Chicken {
// 치킨집 행과 열
int row;
int column;
public Chicken(int row, int column) {
this.row = row;
this.column = column;
}
}
/**
* 재귀메서드로 치킨거리 최솟값 찾기
* @param city : 도시정보를 가진 2차웝 배열
* @param index : 배열에 사용할 인덱스
* @param M : 도시에 있어야 하는 최대 치킨집 개수
* @param chickens : 도시에 있는 모든 치킨집을 저장한 리스트
* @param search : 모든치킨집 중에 M개의 치킨집을 뽑아내서 저장할 리스트
*/
static void recursion(int[][] city, int index, int M, List<Chicken> chickens, List<Chicken> search) {
// M개의 치킨집을 다 고른경우
if (search.size() >= M) {
// 임시 결과 저장 값
int tempResult = 0;
// 도시 탐색
for (int i = 1; i < city.length; i++) {
for (int j = 1; j < city[i].length; j++) {
// 가정 집인 경우
if (city[i][j] == 1) {
// 최소거리값을 저장할 변수
int minDistance = Integer.MAX_VALUE;
// 가정집과 M개의 치킨집 모두 거리 계산
for (Chicken c : search) {
// M개의 치킨집 중 가정집과 거리가 가장 가까운 값으로 거리값 저장
int temp = Math.abs(i-c.row) + Math.abs(j-c.column);
minDistance = Math.min(minDistance, temp);
}
// 구한 최소거리값을 임시 결과변수에 저장
tempResult += minDistance;
}
}
}
// 임시결과 변수와 최종결과 변수 값 중 작은 값을 최종결과 변수에 저장 후 종료
result = Math.min(tempResult, result);
return;
}
// 도시에 있는 치킨집 중에서 M개의 치킨집 뽑는 모든 경우의수 탐색
for (int i = index; i < chickens.size(); i++) {
search.add(chickens.get(i));
recursion(city, i + 1, M, chickens, search);
search.remove(search.size() - 1);
}
}
}
코드에 대한 자세한 설명은 주석으로 달아놓았으니 코드와 함께 읽어보시길 바랍니다.
감사합니다.
728x90
'Algorithm & Data Structure > 문제풀이' 카테고리의 다른 글
[Algorithm] 백준 9095번 (BOJ 9095) 1,2,3 더하기 문제풀이 (Java) (0) | 2021.08.09 |
---|---|
[Algorithm] 백준 17135번 (BOJ 17135) 캐슬 디펜스 문제풀이 (Java) (0) | 2021.08.07 |
[Algorithm] 백준 1005번(BOJ 1005) ACM Craft 문제풀이 (Java) (0) | 2021.07.31 |
[Algorithm] 백준 2252번(BOJ 2252) 줄 세우기 문제풀이 (Java) (0) | 2021.07.31 |
[Algorithm] 백준 15683번(BOJ 15683) 감시 (Java) (0) | 2021.07.29 |
댓글