그리디 문제입니다.
이 문제를 풀기 위해서는 한 가지 아이디어가 필요합니다.
필요 타일의 크기 중 가장 큰 것 먼저 자른다.
즉, 내림차순으로 문제를 해결하면 됩니다.
M*M에서 N*N 만큼 타일을 자르면 아래의 그림과 같이 구역이 나눠집니다.
즉, M*(M-N) 과 (M-N)*N이 남습니다.
문제 전체 접근 순서는 다음과 같습니다.
- 필요 타일의 크기(N*N)들을 구해서 리스트에 저장한다.
- 크기를 내림차순으로 정렬한다.
- 내림차순으로 정렬된 요소를 하나씩 확인하면서 타일을 자른다.
- 타일을 자를 수 있으면 자르고 남은 두 개의 타일을 저장한다.
- 타일을 자를 수 없다면 하나의 새로운 타일을 추가하고 타일을 자른다.
[구현 코드]
import java.io.*;
import java.util.*;
public class Solution {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stz;
int t = Integer.parseInt(br.readLine());
for (int testCase = 1; testCase <= t; testCase++) {
int answer = 0;
stz = new StringTokenizer(br.readLine());
int n = Integer.parseInt(stz.nextToken());
int m = Integer.parseInt(stz.nextToken());
// 1. 필요 타일의 크기(N*N)들을 구해서 리스트에 저장한다.
stz = new StringTokenizer(br.readLine());
List<Integer> needTilesSizes = new ArrayList<>();
for(int i=0; i<n; i++){
int size = Integer.parseInt(stz.nextToken());
needTilesSizes.add((int) Math.pow(2, size));
}
// 2. 크기를 내림차순으로 정렬한다.
needTilesSizes.sort(Collections.reverseOrder());
answer = calNeedTiles(m, needTilesSizes);
System.out.printf("#%d %d" + System.lineSeparator(), testCase, answer);
}
br.close();
}
private static int calNeedTiles(int m, List<Integer> needTilesSizes) {
int count = 1;
List<int[]> rects = new ArrayList<>();
rects.add(new int[]{m, m});
// 3. 내림차순으로 정렬된 요소를 하나씩 확인하면서 타일을 자른다.
for (int needTilesSize : needTilesSizes) {
boolean isNeedNewTile = true;
for(int i=0; i<rects.size(); i++){
int w = rects.get(i)[0];
int h = rects.get(i)[1];
// 3.1 타일을 자를 수 있으면 자르고 남은 두 개의 타일을 저장한다.
if(w >= needTilesSize && h >= needTilesSize){
rects.add(new int[]{w, h-needTilesSize});
rects.add(new int[]{w-needTilesSize, needTilesSize});
rects.remove(i);
isNeedNewTile = false;
break;
}
}
// 3.2 타일을 자를 수 없다면 하나의 새로운 타일을 추가하고 타일을 자른다.
if(isNeedNewTile){
count++;
rects.add(new int[]{m, m-needTilesSize});
rects.add(new int[]{m-needTilesSize, needTilesSize});
}
}
return count;
}
}
'알고리즘' 카테고리의 다른 글
백준 - 17822 원판 돌리기 (0) | 2023.07.22 |
---|---|
SW Expert - 달란트 2 (Java) (0) | 2023.07.19 |
SW Expert - 1267 작업 순서 (0) | 2023.07.16 |
백준 - 1339 단어 수학(Java) (0) | 2023.06.06 |
백준 - 13614 행복 유치원(Java) (0) | 2023.06.05 |