작성일 :

문제 링크

10163번 - 색종이

설명

여러 장의 색종이를 순서대로 올려놓을 때, 각 색종이가 최종적으로 보이는 넓이를 계산하는 시뮬레이션 문제입니다.

  • 모든 색종이는 직사각형이며, 평면의 격자 위에 놓입니다.
  • 이후 놓이는 색종이가 기존의 색종이를 덮을 수 있습니다.
  • 주어진 순서대로 색종이를 모두 놓은 뒤,
    각 색종이 번호에 해당하는 영역이 평면 위에 몇 칸 남아 있는지를 계산해야 합니다.


접근법

  • 평면 전체를 2차원 배열로 표현하고,
    색종이를 덮을 때마다 해당 위치에 색종이 번호를 기록합니다.
  • 이후 전체 평면을 순회하며, 각 색종이 번호가 나타나는 횟수를 세어 최종 넓이를 계산합니다.


이때, 뒤에 올려진 색종이가 기존 색종이를 덮으면 색종이 번호가 바뀌게 되므로,

자연스럽게 가장 마지막에 덮인 색종이만 평면에 남게 됩니다.



Code

C#

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
using System;

class Program {
  static void Main() {
    int[,] board = new int[1001, 1001];
    int n = int.Parse(Console.ReadLine());

    for (int idx = 1; idx <= n; idx++) {
      var input = Console.ReadLine().Split();
      int x = int.Parse(input[0]);
      int y = int.Parse(input[1]);
      int w = int.Parse(input[2]);
      int h = int.Parse(input[3]);

      for (int dy = 0; dy < h; dy++) {
        for (int dx = 0; dx < w; dx++)
          board[y + dy, x + dx] = idx;
      }
    }

    for (int idx = 1; idx <= n; idx++) {
      int area = 0;
      for (int y = 0; y < 1001; y++) {
        for (int x = 0; x < 1001; x++)
          if (board[y, x] == idx) area++;
      }
      Console.WriteLine(area);
    }
  }
}

C++

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
32
#include <bits/stdc++.h>
#define MAX 1001
using namespace std;

int board[MAX][MAX];

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int n; cin >> n;

  for (int i = 1; i <= n; i++) {
    int x, y, w, h; cin >> x >> y >> w >> h;
    for (int dy = 0; dy < h; dy++) {
      for (int dx = 0; dx < w; dx++)
        board[y + dy][x + dx] = i;
    }
  }

  for (int i = 1; i <= n; i++) {
    int area = 0;
    for (int y = 0; y < MAX; y++) {
      for (int x = 0; x < MAX; x++) {
        if (board[y][x] == i) area++;
      }
    }
    cout << area << "\n";
  }

  return 0;
}