| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
Tags
- 프로그래멋
- DP
- Java
- 다익스트라
- 토마토
- 이코테
- 구현
- 완전탐색
- BFS
- 그래프
- 백준
- 분할정복
- Summer/Winter Coding(~2018)
- 프로그래머스
- 깃허브
- 깃허브 프로필
- 조합
- 알고리즘고득점Kit
- 정렬
- GIT
- 자바
- 알고리즘
- 1932
- 정수 삼각형
- 월간 코드 챌린지 시즌1
- 그래프탐색
- 15686
- dfs
- Python
- Lv2
Archives
- Today
- Total
갱스터하우스
[Java] 백준 15686.치킨 배달 본문
➡️문제 링크
https://www.acmicpc.net/problem/15686
💡아이디어
완-탐 / 조합
주어진 치킨집 중 M개를 선택해야한다는 조건을 보고
한 번에 완벽한 M개를 고르는 방법이 있는가? -> X
그렇다면 모든 치킨집 중 임의로 M개를 뽑아 최소 치킨 거리를 뽐내는지 확인해야겠다 싶어
조합을 만들어 탐색했다
✏️문제 풀이
1. 완탐,구현 - 성공
1. 치킨집과 집의 좌표를 각각 저장
2. 전체 치킨집 중 M개를 뽑아 해당 치킨집과 치킨 거리를 구해 비교한다.
import java.io.*;
import java.util.*;
public class Main {
static int N,M;
static int [][] map;
static List<int []> chickenList = new ArrayList<>();
static List<int []> homeList = new ArrayList<>();
static int result = Integer.MAX_VALUE;
static int [] arr;
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
map = new int[N][N];
for(int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for(int j = 0; j < N; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
if(map[i][j] == 2) chickenList.add(new int[] {i, j}); // 치킨집 위치
else if(map[i][j] == 1) homeList.add(new int[] {i, j}); // 집 위치
}
}
if(M == chickenList.size()) {
solve(chickenList);
}else {
arr = new int[M];
recursion(0, 0);
}
// 출력
System.out.println(result);
}
static void recursion(int depth, int start) {
if(depth == M) {
List<int []> tmp = new ArrayList<>();
for(int idx : arr) {
tmp.add(chickenList.get(idx));
}
solve(tmp);
return;
}
for(int i = start; i < chickenList.size(); i++) {
arr[depth] = i;
recursion(depth+1, i+1);
}
}
static void solve(List<int []> list) {
int totalDist = 0;
for(int i = 0; i < homeList.size(); i++) {
int curMinDist = Integer.MAX_VALUE;
int r1 = homeList.get(i)[0];
int c1 = homeList.get(i)[1];
for(int j = 0; j < list.size(); j++) {
int r2 = list.get(j)[0];
int c2 = list.get(j)[1];
int dist = Math.abs(r1-r2) + Math.abs(c1-c2);
curMinDist = Math.min(curMinDist, dist); // 치킨집 리스트 중 치킨 거리 가장 작은 것 추출
}
totalDist+= curMinDist;
}
result = Math.min(result, totalDist);
}
}
2. 완탐, 구현- 성공
다른 사람들의 풀이를 살펴 보니 미리 집과 각 치킨집별 거리를 구한 뒤, 조합을 구현했다
그리고 문제에서는 각 집과 치킨집의 좌표만 필요하기에, 2차원 배열 map은 만들 필요가 없었다
2차원 배열만 보면 무조건 저장하는 습관이 있는데
문제를 잘 읽어 봐야겠다
import java.io.*;
import java.util.*;
public class Main {
static int N,M;
static List<int []> chickenList = new ArrayList<>();
static List<int []> homeList = new ArrayList<>();
static int [][] dist;
static int [] pick;
static int minDist = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
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 i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for(int j = 0; j < N; j++) {
int num = Integer.parseInt(st.nextToken());
if(num == 2) chickenList.add(new int[] {i, j}); // 치킨집 위치
else if(num == 1) homeList.add(new int[] {i, j}); // 집 위치
}
}
// 각 집마다 - 치킨집별 치킨 거리 구하기
dist = new int[homeList.size()][chickenList.size()];
for(int i = 0; i < homeList.size(); i++) {
int r1 = homeList.get(i)[0];
int c1 = homeList.get(i)[1];
for(int j = 0; j < chickenList.size(); j++) {
int r2 = chickenList.get(j)[0];
int c2 = chickenList.get(j)[1];
dist[i][j] = Math.abs(r1-r2) + Math.abs(c1-c2);
}
}
// M개 치킨집 뽑기
pick = new int[chickenList.size()];
recursion(0, 0);
// 출력
System.out.println(minDist);
}
static void recursion(int depth, int start) {
if(depth == M) {
minDist = Math.min(minDist, calDist());
return;
}
for(int i = start; i < chickenList.size(); i++) {
pick[depth] = i;
recursion(depth+1, i+1);
}
}
static int calDist() {
int totalDist = 0;
for(int i = 0; i < homeList.size(); i++) {
int curMinDist = Integer.MAX_VALUE;
for(int j = 0; j < M; j++) {
curMinDist = Math.min(curMinDist, dist[i][pick[j]]);
}
totalDist += curMinDist;
}
return totalDist;
}
}
'코테 문제 > 백준' 카테고리의 다른 글
| [Java] 백준 14502.연구소 (0) | 2026.03.27 |
|---|---|
| [Java] 백준 1753.최단 경로 (0) | 2026.03.17 |
| [Java] 백준 13549.숨바꼭질 3 (0) | 2026.03.12 |
| [Java] 백준 2096.내려가기 (0) | 2026.03.10 |
| [Java] 백준 1916.최소 비용구하기 (0) | 2026.03.09 |