Algorithm/백준
백준 - 스티커 붙이기
whyWhale
2023. 3. 23. 01:27
문제 설명
스티커를 해당 칸에 최대 몇개까지 붙여 0이 아닌칸을 출력하는 문제이다.
주의사항
- 2차원 배열을 회전할 때 회전방향은 시계 방향부터 해야한다.
- 그렇지 않는다면 다르게 칸에 끼워져 정답이랑 값이 멀어지기 때문이다.
풀이
static int autoIncrement = 1;
private static int[][] grid;
private static int n;
private static int m;
static class Shape {
int idx = autoIncrement++;
int n, m;
int map[][];
public Shape(int n, int m, int[][] map) {
this.n = n;
this.m = m;
this.map = map;
}
/**
* 주의 : 90도가 순서대로 돌아가야한다! (다른 회전방향이 먼저 껴지면 정답과 멀어진다.)
* @return
*/
public int[][] rotate() {
int cp[][] = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
cp[i][j]=map[n-1-j][i];
}
}
int temp = n;
this.n = this.m;
this.m = temp;
map = new int[n][m];
return this.map = cp;
}
}
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(reader.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
List<Shape> shapes = new ArrayList<>();
for (int sticker = 0; sticker < k; sticker++) {
st = new StringTokenizer(reader.readLine());
int r = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
int map[][] = new int[r][c];
for (int i = 0; i < r; i++) {
st = new StringTokenizer(reader.readLine());
for (int j = 0; j < c; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
shapes.add(new Shape(r, c, map));
}
grid = new int[n][m];
for (Shape shape : shapes) {
int repeat = 4;
while (repeat-- > 0) {
if (isFit(shape)) {
break;
}
shape.rotate();
}
}
int answer = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] != 0) {
answer++;
}
}
}
System.out.println(answer);
}
private static boolean isFit(Shape shape) {
for (int i = 0; i <= n - shape.n; i++) {
for (int j = 0; j <= m - shape.m; j++) {
if (isAttach(shape, i, j)) {
write(shape, i, j);
return true;
}
}
}
return false;
}
private static boolean isAttach(Shape shape, int startY, int startX) {
for (int i = startY; i < startY + shape.n; i++) {
for (int j = startX; j < startX + shape.m; j++) {
// 이미 칸을 차지하고 있다면
if (shape.map[i - startY][j - startX] == 1 && grid[i][j] != 0) {
return false;
}
}
}
return true;
}
private static void write(Shape shape, int startY, int startX) {
for (int i = startY; i < startY + shape.n; i++) {
for (int j = startX; j < startX + shape.m; j++) {
if (shape.map[i - startY][j - startX] == 1) {
grid[i][j] = shape.idx;
}
}
}
}
public static boolean isOutOfIndex(int ny, int nx) {
return ny < 0 || nx < 0 || ny >= n || nx >= m;
}