Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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
- 코딩테스트준비
- 알고리즘
- 항해99
- 연결 리스트
- 갭체크
- 플로이드-워셜
- 데이터베이스
- 웹
- 코딩테스트
- Java
- 자바
- 코딩테스트사이트추천
- 인접 행렬
- 프로그래밍 언어
- 1일1코테
- 코테공부
- #코드트리 #코딩테스트 #코테공부 #백트래킹 #알고리즘 기초
- 코드트리
- til
- 99클럽
- 개발자루틴
- 파이썬
- 오블완
- 운영체제
- 자료구조
- 개발자취업
- 프로그래머스
- 자바스크립트
- C
- 티스토리챌린지
Archives
- Today
- Total
와드의 블로그
14620번: 꽃길 본문
문제
N x N 크기의 화단에 씨앗 3개를 심어서 꽃을 피우려고 합니다. 꽃이 피면 씨앗이 있는 칸을 포함해 상하좌우로 총 5칸의 공간을 차지하게 됩니다. 꽃끼리 잎이 닿거나 화단 밖으로 나가면 꽃이 죽어버립니다. 화단의 각 칸마다 대여 가격이 주어질 때, 3송이의 꽃을 모두 무사히 피우기 위한 최소 비용을 구하는 문제입니다.
- 입력: 첫째 줄에 화단의 한 변의 길이 N (6 ≤ N ≤ 10)이 주어집니다. 다음 N개의 줄에 걸쳐 화단의 지점당 가격이 주어집니다.
- 출력: 꽃을 심기 위한 최소 비용을 출력합니다.
링크: https://www.acmicpc.net/problem/14620
풀이: 3개의 좌표를 뽑는 완전탐색
화단의 최대 크기가 10 x 10 = 100칸으로 매우 작습니다. 따라서 100칸 중 3칸을 고르는 조합(Combination)을 모두 탐색하여도 시간 초과가 발생하지 않는 전형적인 브루트포스 문제입니다.
- 좌표 리스트 생성: 입력을 받을 때 화단의 모든 (y, x) 좌표를 Node 객체로 만들어 list에 저장해 둡니다. 이를 통해 좌표를 쉽게 순회하고 조합을 구성할 수 있습니다.
- 3개의 씨앗 위치 고르기: 3중 반복문을 사용하여 list에서 서로 다른 3개의 좌표 인덱스(p, q, r)를 고릅니다.
- 비용 계산 및 유효성 검사 (getCost): 선택된 3개의 좌표를 중심으로 꽃이 필 수 있는지 검사합니다.
- visited 배열을 선언하여 꽃잎이 차지하는 자리를 방문 처리합니다.
- 중심 좌표와 상하좌우 4칸(dy, dx)을 확인합니다.
- 만약 화단 범위를 벗어나거나(ny < 0 || nx < 0 || ny >= n || nx >= n), 다른 꽃잎과 이미 겹친다면(visited[ny][nx] == true), 무효한 경우이므로 Integer.MAX_VALUE를 반환하여 최솟값 갱신을 막습니다.
- 무사히 꽃을 피울 수 있다면 5칸의 가격을 모두 sum에 더해주고 누적된 비용을 반환합니다.
- 최솟값 갱신: 반환된 비용을 바탕으로 전체 최솟값(ans)을 갱신하고, 모든 조합의 탐색이 끝난 후 출력합니다.
코드
import java.io.*;
import java.util.*;
public class Main {
// 최소 비용을 구해야 하므로 정수 최댓값으로 초기화
static int n, ans = Integer.MAX_VALUE;
static int[][] a;
static List<Node> list = new ArrayList<>();
// 상하좌우 델타 배열
static int[] dy = {-1, 0, 1, 0};
static int[] dx = {0, 1, 0, -1};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
n = Integer.parseInt(br.readLine());
a = new int[n][n];
// 화단 가격 입력 및 모든 좌표를 리스트에 저장
for (int i = 0; i < n; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < n; j++) {
a[i][j] = Integer.parseInt(st.nextToken());
list.add(new Node(i, j));
}
}
// 리스트에 담긴 좌표 중 3개를 뽑는 조합 (3중 for문)
for (int i = 0; i < list.size() - 2; i++) {
for (int j = i + 1; j < list.size() - 1; j++) {
for (int k = j + 1; k < list.size(); k++) {
// 선택된 3개의 씨앗 위치로 최소 비용 갱신 시도
ans = Math.min(ans, getCost(i, j, k));
}
}
}
bw.write(ans + "");
bw.flush();
bw.close();
br.close();
}
// 3개의 좌표(인덱스 p, q, r)에 꽃을 피울 때의 비용 계산
static int getCost(int p, int q, int r) {
Node[] nodes = new Node[3];
nodes[0] = list.get(p);
nodes[1] = list.get(q);
nodes[2] = list.get(r);
int sum = 0;
boolean[][] visited = new boolean[n][n]; // 꽃잎 겹침 방지용 방문 배열
for (int i = 0; i < 3; i++) {
int y = nodes[i].y;
int x = nodes[i].x;
// 씨앗 중심부 처리
sum += a[y][x];
visited[y][x] = true;
// 상하좌우 꽃잎 처리
for (int j = 0; j < 4; j++) {
int ny = y + dy[j];
int nx = x + dx[j];
// 화단을 벗어나거나 다른 꽃잎과 겹치면 실패 처리 (최댓값 반환)
if (ny < 0 || nx < 0 || ny >= n || nx >= n || visited[ny][nx]) {
return Integer.MAX_VALUE;
}
sum += a[ny][nx];
visited[ny][nx] = true;
}
}
return sum; // 3송이 모두 성공적으로 피웠다면 총 비용 반환
}
// 좌표를 담기 위한 이너 클래스
static class Node {
int y, x;
Node(int y, int x) {
this.y = y;
this.x = x;
}
}
}
알고리즘 분류
브루트포스 알고리즘 (완전탐색), 조합 (Combination)
'PS > B.O.J' 카테고리의 다른 글
| 1987번: 알파벳 (0) | 2026.03.27 |
|---|---|
| 1189번: 컴백홈 (0) | 2026.03.26 |
| 13913번: 숨바꼭질 4 (0) | 2026.03.26 |
| 12851번: 숨바꼭질 2 (0) | 2026.03.25 |
| 2589번: 보물섬 (0) | 2026.03.25 |