[문제 링크]
https://www.acmicpc.net/problem/15686
문제 설명
0-빈칸, 1-집, 2-치킨집
치킨거리 = 집(x1, y1)과 가장 가까운 치킨집(x2, y2) 사이의 거리 → |(x1-x2)| + |(y1-y2)|
도시의 치킨거리 = 모든 집의 치킨 거리의 합
치킨집을 최대 m개를 골랐을 때, 도시의 치킨거리의 최소값을 구한다.
문제 풀이
- 도시에 대한 정보를 입력받으면서 치킨집과 집의 위치 정보를 리스트에 따로 저장한다.
- dfs() : dfs 알고리즘을 사용해서 m개의 치킨집을 고른다. 이 때, 치킨집의 위치를 따로 저장한 리스트를 사용해서 m개의 치킨집을 고른다.
- cityChicken() : houseChicken() 에서 구한 치킨거리를 모두 더해서 도시의 치킨거리를 구한다. 그리고 도시의 치킨거리의 최솟값을 구한다.
- houseChicken() : 하나의 집에 대해서 m개의 치킨집을 돌면서 거리가 가장 가까운 치킨집과의 치킨거리를 구한다.
전체 코드
import java.io.*;
import java.util.ArrayList;
import java.util.StringTokenizer;
class Position {
int x;
int y;
public Position(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Main {
static int n, m, result;
static int cityMin = Integer.MAX_VALUE;
static int[][] cities;
static int[] choose; //선택한 m개의 치킨집
static ArrayList<Position> chicken = new ArrayList<>(); //치킨집의 위치 정보
static ArrayList<Position> house = new ArrayList<>(); //집의 위치 정보
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken()); //도시의 크기
m = Integer.parseInt(st.nextToken()); //폐업시키지 않을 치킨집의 최대 개수
cities = new int[n][n];
choose = new int[m];
//도시 정보 입력
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < n; j++) {
cities[i][j] = Integer.parseInt(st.nextToken());
//치킨집의 위치 정보 저장
if (cities[i][j] == 2) {
chicken.add(new Position(i, j));
}
//집의 위치 정보 저장
if(cities[i][j] == 1)
house.add(new Position(i, j));
}
}
dfs(0, 0);
System.out.println(result);
}
public static void dfs(int cnt, int start) {
//종료조건 : 고른 치킨집의 개수가 m인 경우
if (cnt == m) {
result = cityChicken();
return;
}
for (int i = start; i < chicken.size(); i++) {
choose[cnt] = i; //선택한 치킨집의 인덱스 저장
dfs(cnt + 1, i + 1);
}
}
//도시의 치킨거리의 최솟값 구하는 메서드
public static int cityChicken() {
int sum = 0;
for (int i = 0; i < house.size(); i++) {
int houseMin = houseChicken(house.get(i));
sum += houseMin;
}
cityMin = Math.min(cityMin, sum);
return cityMin;
}
//각 집의 치킨거리를 구하는 메서드
public static int houseChicken(Position position) {
int houseMin = Integer.MAX_VALUE;
int houseX = position.x;
int houseY = position.y;
for (int i = 0; i < choose.length; i++) {
int chickenX = chicken.get(choose[i]).x;
int chickenY = chicken.get(choose[i]).y;
int distance = Math.abs((houseX - chickenX)) + Math.abs((houseY - chickenY));
houseMin = Math.min(houseMin, distance);
}
return houseMin;
}
}
'PS > 백준' 카테고리의 다른 글
[백준][Java] 6603번 : 로또 (0) | 2025.05.27 |
---|---|
[백준][Java] 15649번 : N과 M(1) (0) | 2025.05.15 |
[백준][Java]11053번 : 가장 긴 증가하는 부분 수열 (0) | 2025.04.29 |
[백준][Java] 2579번 : 계단 오르기 (0) | 2025.04.16 |
[백준][Java] 10025번 : 적록색약 (0) | 2025.02.06 |