일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 우유아야
- 텐션 업 10기 화이팅
- SeongSeobDang
- SSAFY IM/A
- BFS
- DP
- 수학
- SSAFY 10기 화이팅
- have a nice day
- 코로나 싫어요
- Hamming weight
- 아자아자 화이팅
- LeetCode #릿코드 #좋은 하루 되세요 #Have a nice day
- 모르고리즘
- amazon
- 우유가옆으로넘어지면아야
- Java 환경 설정
- SSAFY 테스트
- 텐션 업 10기!
- SSAFY 화이팅
- DFS
- 자고 싶다
- Have a nice day.
- I am Korean
- 우유가 옆으로 넘어지면 아야
- 네트워크
- 자료구조
- Have a good day :)
- HAVE A GOOD DAY
- Today
- Total
Hope Everyone Is Happy
[골드2] 17136. 색종이 붙이기(Java) 본문
[골드2] 17136. 색종이 붙이기(Java)
J 크 2023. 10. 3. 22:03https://www.acmicpc.net/problem/17136
17136번: 색종이 붙이기
<그림 1>과 같이 정사각형 모양을 한 다섯 종류의 색종이가 있다. 색종이의 크기는 1×1, 2×2, 3×3, 4×4, 5×5로 총 다섯 종류가 있으며, 각 종류의 색종이는 5개씩 가지고 있다. <그림 1> 색종이를 크
www.acmicpc.net
내 연휴 돌려줘요
※ 문제를 요약하면 아래와 같습니다.
▶ 1x1 ~ 5x5 크기의 정사각형 모양 색종이가 각각 5장씩 존재, 10x10인 종이 위에 부착
▶ 겹쳐서 붙이거나 종이 경계밖으로 나가서는 안돼며, 0이 적힌 칸에는 색종이가 있으면 안됌
▶ 종이의 상태가 0과 1로 주어졌을 때, 필요한 색종의 최소 갯수 출력
▶ Input : 10개의 줄에 종이의 각 칸에 적힌 수 입력
▶ Output : 필요한 색종이의 최소 개수 출력, 1을 모두 덮는 것이 불가능한 경우, -1 출력
◈ Input - 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
◈ Output - 1
0
◈ Input - 2
0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
◈ Output - 2
4
◈ Input - 3
0 0 0 0 0 0 0 0 0 0
0 1 1 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
◈ Output - 3
5
◈ Input - 4
0 0 0 0 0 0 0 0 0 0
0 1 1 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
◈ Output - 4
-1
◈ Input - 5
0 0 0 0 0 0 0 0 0 0
0 1 1 0 0 0 0 0 0 0
0 1 1 1 0 0 0 0 0 0
0 0 1 1 1 1 1 0 0 0
0 0 0 1 1 1 1 0 0 0
0 0 0 0 1 1 1 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
◈ Output - 5
7
◈ Input - 6
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
◈ Output - 6
4
◎ 코드 작성 전, 아래와 같이 솔루션을 정리하였습니다.
▶ 색종이의 최대 크기인 5x5 부터 탐색을 진행하여도 예외 케이스 발생
▶ 각각의 색종이 사용의 경우의 수를 전부 탐색
(크기별로 5장씩만 사용 가능하며 크기가 작은 색종이를 먼저 사용해야 최소 사용 갯수일 경우도 존재)
▶ 색종이를 덮었는지 확인하기 위한 10x10 크기의 boolean 형 배열 선언
▶ 각 크기별 색종이의 사용 횟수 체크를 위한 int형 배열 선언
▶ 사각형 탐색을 범위 체크 + 값1 체크 + 방문 여부 조건을 설정하여 메서드(함수)로 선언
▶ 부분집합 재귀 탐색을 활용하여 완전 탐색, 색종이가 최소로 사용된 갯수를 저장
▶ 현재 탐색 중인 행과,열 사용된 색종이의 수를 재귀 함수 인자로 반환, 탐색이 더 이상 불가능한 경우 최소값 비교
▶ 재귀 과정에서 이미 최소 탐색 횟수를 넘었을 경우 탐색 종료 (빽트래킹!)
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
static int nMin, nTemp;
static boolean[][] barrMap, barrCheck;
static int[] narrPaper;
final static int SIZE = 10;
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bWriter = new BufferedWriter(new OutputStreamWriter(System.out));
barrMap = new boolean[SIZE][SIZE];
barrCheck = new boolean[SIZE][SIZE];
narrPaper = new int[5];
nMin = Integer.MAX_VALUE;
// 색종이 입력 받자
for (int i = 0; i < SIZE; i++) {
StringTokenizer st = new StringTokenizer(bReader.readLine());
for (int j = 0; j < SIZE; j++) {
if (Integer.parseInt(st.nextToken()) == 1)
barrMap[i][j] = true;
}
}
// 가장 큰 사이즈인 5부터 검사를 시작
// 하지만 5가 들어가있어서 더 많을 수도 있으니
// 다른 경우도 검사해보자
Arrays.fill(narrPaper, 5);
Paper(0, 0, 0);
if (nMin == Integer.MAX_VALUE)
nMin = -1;
bWriter.write(String.valueOf(nMin));
bWriter.close();
}
private static void Paper(int nRow, int nCol, int nCount) {
// 색종이가
int nSearchRow = -1;
int nSearchCol = -1;
for (int i = nRow; i < SIZE; i++) {
for (int j = nCol; j < SIZE; j++) {
if (barrMap[i][j] && !barrCheck[i][j]) {
nSearchRow = i;
nSearchCol = j;
break;
}
}
if (nSearchRow != -1)
break;
}
if (nSearchRow == -1) {
if (nMin > nCount && IsDone())
nMin = nCount;
return;
}
if (nCount > nMin)
return;
for (int k = 5; k > 0; k--) {
if (!barrCheck[nSearchRow][nSearchCol] && narrPaper[k - 1] > 0) {
// 사각형인 것을 확인했다믄
if (RectMasking(nSearchRow, nSearchCol, k)) {
narrPaper[k - 1]--;
Paper(nSearchRow, 0, nCount + 1);
narrPaper[k - 1]++;
Checking(nSearchRow, nSearchCol, k, false);
}
}
}
// 색종이가 다 붙여졌다??
}
// 사각형 검사
private static boolean RectMasking(int nRow, int nCol, int nSize) {
for (int i = nRow; i < nRow + nSize; i++) {
for (int j = nCol; j < nCol + nSize; j++) {
// 사각형이 될 수 없다
// 범위 밖, 1이 없다, 이미 체크 했다
if (i < 0 || j < 0 || i >= SIZE || j >= SIZE || !barrMap[i][j] || barrCheck[i][j])
return false;
}
}
Checking(nRow, nCol, nSize, true);
// System.out.println(nRow + " " + nCol + " " + nSize);
// 여기 왔다는건 사각형이라는 뜻이다.
return true;
}
private static void Checking(int nRow, int nCol, int nSize, boolean bSwitch) {
for (int i = nRow; i < nRow + nSize; i++) {
for (int j = nCol; j < nCol + nSize; j++) {
barrCheck[i][j] = bSwitch;
}
}
}
// 모든 1이 (색종이가) 체크가 되었나???
private static boolean IsDone() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (barrMap[i][j] != barrCheck[i][j]) {
System.out.println("ROW : " + i + " / COL : " + j);
return false;
}
}
}
return true;
}
}
Good Luck! (피드백 감사합니다!)
'※ 백준 (Baekjoon) > [Java] 문제 풀이 ( Solve the problems)' 카테고리의 다른 글
[골드5] 2293. 동전 1(Java) (2) | 2023.10.03 |
---|---|
[실버 4] 2839. 설탕 배달 / DP (Java) (2) | 2023.10.03 |
[실버1] 14888. 연산자 끼워넣기(Java) (0) | 2023.10.03 |
[골드3] 17135. 캐슬 디펜스(Java) (0) | 2023.09.28 |
[골드5] 7562. 파이프 옮기기(Java) (0) | 2023.09.27 |