https://www.acmicpc.net/problem/18808
어려운 문제는 아니고 그냥 구현 문제이다. 그런데 스티커 회전이라든지, map에 붙일 수 있는지 없는지 이차원 배열의 범위를 탐색한다든지 짜잘하게 신경써야 할 것이 많다. 그리고 그만큼 실수하기 쉬운 문제이다. 다행히 몇 번 디버깅하면서 맞출 수 있었는데, 그래도 다음에 다시 풀면서 꼼꼼히 생각하자는 의미로 기록한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
static int n; // 세로
static int m; // 가로
static int k; // 스티커 개수
static int[][] map;
static int answer = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
k = Integer.parseInt(st.nextToken());
map = new int[n][m];
for (int i = 0; i < k; i++) {
// 스티커 입력받기
st = new StringTokenizer(br.readLine());
int r = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
int[][] sticker = new int[r][c];
for (int j = 0; j < r; j++) {
st = new StringTokenizer(br.readLine());
for (int k = 0; k < c; k++) {
sticker[j][k] = Integer.parseInt(st.nextToken());
}
}
// 스티커 붙이기
putSticker(sticker);
}
// 스티커가 붙은 칸 수 계산
getStickerArea();
System.out.println(answer);
}
private static void putSticker(int[][] sticker) {
for (int i = 0; i < 4; i++) {
// 지금 방향에서 붙일 수 있는지 확인
int stickerX = sticker[0].length; // 스티커의 가로 길이
int stickerY = sticker.length; // 스티커의 세로 길이
for (int j = 0; j <= (n - stickerY); j++) {
for (int k = 0; k <= (m - stickerX); k++) {
// map 범위를 벗어나지 않는지 확인
if (j + stickerY > n || k + stickerX > m) {
continue;
}
// 붙이기(붙였으면 끝내기)
if (canPut(sticker, j, k)) {
return;
}
}
}
// 90도로 스티커 회전
sticker = rotation(sticker);
}
}
private static boolean canPut(int[][] sticker, int startY, int startX) {
int stickerX = sticker[0].length; // 스티커의 가로 길이
int stickerY = sticker.length; // 스티커의 세로 길이
// 붙일 수 있는지 확인 (스티커가 1인데 map도 1이면 못붙임)
for (int i = 0; i < stickerY; i++) {
for (int j = 0; j < stickerX; j++) {
if (sticker[i][j] == 1 && map[i + startY][j + startX] == 1) {
return false;
}
}
}
// 붙일 수 있으면 스티커 붙이기
for (int i = 0; i < stickerY; i++) {
for (int j = 0; j < stickerX; j++) {
if (sticker[i][j] == 1) {
map[i + startY][j + startX] = 1;
}
}
}
return true;
}
private static int[][] rotation(int[][] sticker) {
int newX = sticker.length;
int newY = sticker[0].length;
int[][] newSticker = new int[newY][newX];
for (int i = 0; i < newX; i++) {
for (int j = 0; j < newY; j++) {
newSticker[j][newX - i - 1] = sticker[i][j];
}
}
return newSticker;
}
private static void getStickerArea() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (map[i][j] == 1) {
answer++;
}
}
}
}
}
'CS > Algorism' 카테고리의 다른 글
[백준] 1926. 그림 (1) | 2023.12.26 |
---|---|
[백준] 10816. 숫자 카드 2 (0) | 2023.12.11 |
[백준] 1744. 수 묶기 (1) | 2023.12.06 |
[백준] 11501. 주식 (2) | 2023.12.06 |
[백준] 2457. 공주님의 정원 (2) | 2023.12.05 |