백준 14620 - 꽃길
Updated:
Java
14620 번 - 꽃길
문제
접근 방법
보통 백트래킹으로 해결하지만, 조합으로 3개의 숫자를 뽑고 그 수를 좌표로 반환하여 화단에 꽃을 놓아보는 방식으로 해결하였다.
DFS의 조합을 통해 0부터 (n-2)^2 까지의 수 중에서 3개를 뽑는다.
(n-2)^2인 이유는 꽃의 중심점을 화단의 끝에다 두면 꽃을 필 수가 없기 때문이다.
문제의 화단의 크기는 6*6
이므로, 0 ~ 4*4
까지의 수를 3개 뽑는다.
이후 뽑은 3개의 수를 좌표로 변환한다.
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
예를들어, [0, 5, 11]을 뽑았으면 {[0,0], [1,1], [2,3]} 가 된다.
뽑은 3개의 점을 화단에 놓고 [상,하,좌,우] 꽃을 두어 서로 안겹치는지 확인하고,
겹치지 않으면 해당 위치의 화단 가격을 계산한다.
이후 계산한 값의 최소를 구한다.
코드
import java.util.*;
import java.io.*;
public class Main {
static int n, m, m2, result;
static int[][] price;
static int[] sel;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stk;
n = stoi(br.readLine());
m = n - 2;
m2 = (int)Math.pow(m, 2);
price = new int[n][n];
sel = new int[3];
for(int i = 0; i < n; i++) {
stk = new StringTokenizer(br.readLine());
for(int j = 0; j < n; j++) {
price[i][j] = stoi(stk.nextToken());
}
}
result = Integer.MAX_VALUE;
DFS(0,0);
System.out.println(result);
br.close();
}
// 꽃을 놓을 수 있는 중심점 3곳을 뽑는다.
private static void DFS(int lv, int st) {
if(lv == 3) {
int rt = chkValid();
if(rt != -1) { // -1이 아니면 화단에 꽃을 놓아 그 금액이 반환되었다는 뜻이다
result = Math.min(result, rt);
}
return;
}
for(int i = st; i < m2; i++) {
sel[lv] = i;
DFS(lv + 1, i + 1);
}
}
static int[] yArr = new int[3];
static int[] xArr = new int[3];
static boolean[][] putFwr;
// 세 점에 꽃을 놓을 수 있는지 판단
private static int chkValid() {
// 구한 3점의 y,x 좌표를 구한다
for(int i = 0; i < 3; i++) {
yArr[i] = sel[i] / m;
xArr[i] = sel[i] % m;
}
putFwr = new boolean[n][n];
int y,x,ny,nx;
int dy[] = new int[] {-1,1,0,0};
int dx[] = new int[] {0,0,-1,1};
for(int i = 0; i < 3; i++) {
y = yArr[i] + 1;
x = xArr[i] + 1;
// 만약 꽃을 놓으려는 지점에 이미 꽃이 있으면
if(putFwr[y][x] == true)
return -1;
putFwr[y][x] = true;
// 꽃 중심에서 상하좌우 꽃을 놔둔다
for(int j = 0; j < 4; j++) {
ny = y + dy[j];
nx = x + dx[j];
if(putFwr[ny][nx] == true)
return -1;
putFwr[ny][nx] = true;
}
}
// 여기까지 온 것이면 3개의 꽃을 놓았다는 것
int sum = 0;
// 꽃을 심은 화단의 가격을 계산
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(putFwr[i][j]) {
sum += price[i][j];
}
}
}
return sum;
}
static int stoi(String str) {
return Integer.parseInt(str);
}
}