📖 문제
17136번: 색종이 붙이기
<그림 1>과 같이 정사각형 모양을 한 다섯 종류의 색종이가 있다. 색종이의 크기는 1×1, 2×2, 3×3, 4×4, 5×5로 총 다섯 종류가 있으며, 각 종류의 색종이는 5개씩 가지고 있다. <그림 1> 색종이를 크
www.acmicpc.net
💡 풀이 방식
• 브루트포스 + 백트래킹
- 최소 색종이 갯수 사용 ⇒ 큰 종이부터 붙이기 ⇒ 그리디
- 완전탐색 ⇒ 브루트포스 + 백트래킹
- N X N 범위 내에 모두 1이 존재한다면, N X N 색종이를 붙였다 떼는 작업 반복
1. 종이 배열에 종이의 최대 갯수 저장
2. DFS 활용해 백트래킹 시도
- 기본 탐색 방향 : 가로
- 끝 칸 도착 시, 아랫줄 첫 칸으로 이동
3. 좌표가 맨 마지막 점 도달 시, 지금까지 붙인 종이 갯수 반환
💥 유의사항
[종료 조건] x가 9이고, y가 10일 때
🔺 코드
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
import java.util.*;
import java.io.*;
public class Main {
static int[] paper = {0, 5, 5, 5, 5, 5}; // 각 종이의 남은 갯수 저장 배열
static int[][] map = new int[10][10];
static int ans = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
for(int i = 0 ; i < 10 ; i++) {
st = new StringTokenizer(br.readLine(), " ");
for(int j = 0 ; j < 10 ; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
dfs(0, 0, 0); // (0,0)부터 오른쪽 아래로 이동하며 색종이 덮어 나감
System.out.println(ans == Integer.MAX_VALUE ? -1 : ans);
}
// DFS + 백트래킹
private static void dfs(int r, int c, int cnt) {
// 맨 끝 점 도달 시 종료
if(r >= 9 && c > 9) {
ans = Math.min(ans, cnt);
return;
}
// 최솟값 계산하는데 cnt가 ans보다 커지는 순간, 더 이상 탐색할 필요 X
if(ans <= cnt) {
return;
}
// 오른쪽으로 이동하다 범위 벗어나면 아래 줄로 이동
if(c > 9) {
dfs(r + 1, 0, cnt);
return;
}
if(map[r][c] == 1) {
for(int i = 5 ; i >= 1 ; i--) { // 제일 큰 색종이 크기부터 붙일 수 있는지 확인 (그리디)
if(paper[i] > 0 && isAttach(r, c, i)) {
attach(r, c, i, 0); // 현재 위치에 i 크기의 색종이 붙임
paper[i]--;
dfs(r, c + 1, cnt + 1);
attach(r, c, i, 1); // 붙였던 색종이 다시 뗌
paper[i]++;
}
}
}
else { // 현재 위치에 색종이 둘 수 없으면, 오른쪽으로 이동
dfs(r, c + 1, cnt);
}
}
// 색종이 붙이고 떼는 메소드
private static void attach(int r, int c, int size, int state) {
for(int i = r ; i < r + size ; i++) {
for(int j = c ; j < c + size ; j++) {
map[i][j] = state;
}
}
}
// 색종이 붙일 수 있는지 확인
private static boolean isAttach(int r, int c, int size) {
for(int i = r ; i < r + size ; i++) {
for(int j = c ; j < c + size ; j++) {
if(i < 0 || i >= 10 || j < 0 || j >= 10)
return false;
if(map[i][j] != 1)
return false;
}
}
return true;
}
}
|
cs |
💦 어려웠던 점
- 큰 종이부터 사용할 생각은 했는데 어떻게 오른쪽 아래 갯수를 (+1,+1)씩 증가시키면서 비교하지?라고 생각하였다.
- 직접 그려보고 이해해야겠당ㅠ
- 조건이 꽤 많은 것 같아서 하나라도 빠지지 않게 미리 작성해두고 진행해야 할 것 같다.
1회독 | 2회독 | 3회독 | 4회독 | 5회독 |
V |
(참고)
[백준]17136: 색종이 붙이기 - JAVA
[백준]17136: 색종이 붙이기 - JAVA www.acmicpc.net/problem/17136 17136번: 색종이 붙이기 과 같이 정사각형 모양을 한 다섯 종류의 색종이가 있다. 색종이의 크기는 1×1, 2×2, 3×3, 4×4, 5×5로 총 다섯 종류가
moonsbeen.tistory.com
[BOJ] 백준 17136번 : 색종이 붙이기 (JAVA)
steady-coding.tistory.com
[백준 17136] 색종이 붙이기(Java)
문제 링크 : https://www.acmicpc.net/problem/17136이 문제는 백트래킹을 이용하여 풀 수 있습니다. 이 문제는 문제에서 얘기한 조건을 차례대로 구현해나가면 풀 수 있습니다.기본적인 탐색은 가로 방향
velog.io
자바(백준) 17136 색종이 붙이기
오답 노트 & 새로 알게 된 점 처음 풀이 빨간색 1을 만날 때 모든 방향을 다 조사해야하나 라는 생각이 들었다. 하지만 1이 있는 곳 모두 완탐을 하게 되면 오른쪽 아래(초록색) 부분만 하면 된다
c-king.tistory.com
'코테 > 백준' 카테고리의 다른 글
[백준/JAVA] 1244번: 스위치 켜고 끄기 (0) | 2024.01.09 |
---|---|
[백준/JAVA] 1325번: 효율적인 해킹 (0) | 2024.01.04 |
[백준/JAVA] 22858번: 원상 복구 (small) (0) | 2023.12.31 |
[백준/JAVA] 21608번: 상어 초등학교 (0) | 2023.12.28 |
[백준/JAVA] 12933번: 오리 (0) | 2023.12.28 |