
백준 17136번 : 색종이 붙이기(삼성 SW 역량 테스트)
17136번: 색종이 붙이기
<그림 1>과 같이 정사각형 모양을 한 다섯 종류의 색종이가 있다. 색종이의 크기는 1×1, 2×2, 3×3, 4×4, 5×5로 총 다섯 종류가 있으며, 각 종류의 색종이는 5개씩 가지고 있다. <그림 1> 색종이를 크
www.acmicpc.net
그리디 + 백트래킹으로 해결할 수 있는 문제
나는 재귀를 이용하여 문제를 풀었다.
배열을 돌면서 큰 색종이부터 붙일 수 있는지 확인한다.(그리드 방식)
<1>현재 위치에서 5x5 크기의 색종이를 붙일 수 있으면 붙인다.
<2>다음 위치로 이동해서, 5x5 크기의 색종이를 붙일 수 있으면 붙인다.
...
<n-1>
<n>배열의 마지막 위치로 이동해서 5x5 크기의 색종이를 붙일 수 있으면 붙인다.
마지막 위치에서 색종이 크기를 줄여가며 매 크기마다 붙일 수 있는지 확인한다.
1x1 크기의 색종이까지 붙일 수 있는지 확인했으면, 다시 전 위치로 돌아간다.
<n-1>이 전에 5x5 색종이를 붙였었다면, 이번에는 4x4 색종이를 붙일 수 있는지 확인하고 붙인다.
다시, 다음위치로 이동해서 5x5 크기부터 1x1 크기 색종이까지 붙여본다.
위 과정을 재귀를 사용하여 반복한다.
위 과정을 재귀로 반복하면서 매번 배열을 다 돌면, 사용한 총 색종이 개수가 최소인지 판정한다.
소스코드:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.*; | |
public class n17136 { | |
static int[][] paper = new int[10][10]; | |
static int[] use = { 0, 0, 0, 0, 0, 0 }; | |
static int min = Integer.MAX_VALUE; | |
public static void main(String[] args) throws Exception { | |
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); | |
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); | |
for (int i = 0; i < 10; i++) { | |
String[] sarr = br.readLine().split(" "); | |
for (int j = 0; j < 10; j++) { | |
paper[i][j] = Integer.parseInt(sarr[j]); | |
} | |
} | |
comb(0, 0); | |
if (min == Integer.MAX_VALUE) | |
bw.write(-1 + "\n"); | |
else | |
bw.write(min + "\n"); | |
bw.flush(); | |
} | |
public static void comb(int sr, int sc) { | |
if (sr >= 10) { // 배열의 끝까지 탐색을 마치면 | |
int cnt = 0; | |
for (int i = 1; i <= 5; i++) | |
cnt += use[i]; | |
min = Math.min(min, cnt); | |
return; | |
} | |
if (paper[sr][sc] == 1) { | |
for (int size = 5; size >= 1; size--) { | |
boolean res = solve(new Pos(sr, sc), size); | |
if (!res) | |
continue; | |
for (int i = sr; i < sr + size; i++) { | |
for (int j = sc; j < sc + size; j++) { | |
paper[i][j] = 0; | |
} | |
} | |
use[size]++; | |
if (sc == 9) // 현재 위치가 열의 마지막이면 | |
comb(sr + 1, 0); // 다음 행으로 이동한다. | |
else | |
comb(sr, sc + 1); // 열의 마지막이 아니라면 다음열로 이동한다. | |
for (int i = sr; i < sr + size; i++) { | |
for (int j = sc; j < sc + size; j++) { | |
paper[i][j] = 1; | |
} | |
} | |
use[size]--; | |
} | |
} | |
else { | |
if (sc == 9) | |
comb(sr + 1, 0); | |
else | |
comb(sr, sc + 1); | |
} | |
} | |
public static boolean solve(Pos pos, int size) { | |
boolean flag = true; | |
for (int i = pos.r; i < pos.r + size; i++) { | |
for (int j = pos.c; j < pos.c + size; j++) { | |
if (i >= 10 || j >= 10 || paper[i][j] == 0) { | |
flag = false; | |
break; | |
} | |
} | |
if (!flag) | |
break; | |
} | |
if (flag && use[size] < 5) | |
return true; | |
// size 크기의 색종이를 붙일 수 없거나, 색종이를 모두 다 사용했으면 false | |
return false; | |
} | |
static class Pos { | |
int r, c; | |
Pos(int r, int c) { | |
this.r = r; | |
this.c = c; | |
} | |
} | |
} |
'BOJ > 삼성 SW 역량테스트' 카테고리의 다른 글
[백준 20061번] 모노미노도미노 2 (java) (0) | 2021.04.17 |
---|---|
[백준 17822번] 원판 돌리기 (java) (0) | 2021.04.15 |
[백준 17837번] 새로운 게임 2 (java) (0) | 2021.04.14 |
[백준 5373번] 큐빙 (java) (0) | 2021.03.18 |
[백준 13460번] 구슬 탈출 2 (java) (0) | 2019.09.18 |