https://www.acmicpc.net/problem/15686
Gold V
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class Main {
private static int[][] dist;
private static int N;
private static int M;
private static int house_cnt;
private static int chicken_store_cnt;
private static class Pair {
int first;
int second;
Pair(int f, int s) {
this.first = f;
this.second = s;
}
int getFirst() {
return this.first;
}
int getSecond() {
return this.second;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
house_cnt = 0;
chicken_store_cnt = 0;
ArrayList<Pair> house_pos = new ArrayList<>(2*N);
ArrayList<Pair> chicken_store_pos = new ArrayList<>(13);
for (int i = 0; i < N; ++i) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; ++j) {
int val = Integer.parseInt(st.nextToken());
if (val == 1) { //house
house_cnt++;
house_pos.add(new Pair(i, j));
}
else if (val == 2) { //chicken store
chicken_store_cnt++;
chicken_store_pos.add(new Pair(i, j));
}
}
}
dist = new int[chicken_store_cnt][house_cnt];
for (int i = 0; i < chicken_store_cnt; ++i) {
for (int j = 0; j < house_cnt; ++j) {
dist[i][j] = Math.abs(house_pos.get(j).getFirst() - chicken_store_pos.get(i).getFirst())
+ Math.abs(house_pos.get(j).getSecond() - chicken_store_pos.get(i).getSecond());
}
}
System.out.print(backtrack());
}
private static int backtrack() {
int min = Integer.MAX_VALUE;
int limit = chicken_store_cnt - 1;
int[] stack = new int[M];
int[] min_dist = new int[house_cnt];
for (int i = 0; i < M; ++i) {
stack[i] = i;
}
while (true) {
//for (int i = 0; i < M; ++i) {
// System.out.printf("%d ", stack[i]);
//}
//System.out.print("\n");
//calculate min
for (int i = 0; i < M; ++i) {
for (int j = 0; j < house_cnt; ++j) {
if (i == 0) {min_dist[j] = dist[stack[i]][j];}
if (dist[stack[i]][j] < min_dist[j]) {
min_dist[j] = dist[stack[i]][j];
}
}
}
//check if it's the smallest
int sum = 0;
for (int i = 0; i < house_cnt; ++i) {
sum += min_dist[i];
}
if (sum < min) {min = sum;}
//back-tracking
int idx = M-1;
while (stack[idx] >= limit) {
idx--;
limit--;
if (idx == -1) break;
}
if (idx == -1) break;
stack[idx] = stack[idx] + 1;
while (idx < M - 1) {
stack[idx+1] = stack[idx]+1;
idx++;
limit++;
}
}
return min;
}
}
미리 모든 치킨 거리를 계산 -> 스택 활용 백트래킹
Java에 있는 Stack
을 안 쓰고 배열을 사용한 이유는 메모리 사용량 좀 줄일려고.
백트래킹에서 각 조합에 따른 최소 거리를 구할 때 Stack
의 내용물을 다 사용하기는 하나, 사실 이건 Stack
의 iterator
을 통해 구현하는 것이 가능하기 때문에 구현상으로 Java의 Stack
을 안 쓸 이유는 별로 없다.
오늘 처음 알았는데 javafx
를 백준에서 못써가지고 Pair
은 직접 만들었다.