문제
가로, 세로의 크기가 각각 100인 정사각형 모양의 흰색 도화지가 있다. 이 도화지 위에 가로, 세로의 크기가 각각 10인 정사각형 모양의 검은색 색종이를 색종이의 변과 도화지의 변이 평행하도록 붙인다. 이러한 방식으로 색종이를 한 장 또는 여러 장 붙인 후 색종이가 붙은 검은 영역의 둘레의 길이를 구하는 프로그램을 작성하시오.
예를 들어 흰색 도화지 위에 네 장의 검은색 색종이를 <그림 1>과 같은 모양으로 붙였다면 검은색 영역의 둘레는 96 이 된다.
입력
첫째 줄에 색종이의 수가 주어진다. 이어 둘째 줄부터 한 줄에 하나씩 색종이를 붙인 위치가 주어진다. 색종이를 붙인 위치는 두 개의 자연수로 주어지는데 첫 번째 자연수는 색종이의 왼쪽 변과 도화지의 왼쪽 변 사이의 거리이고, 두 번째 자연수는 색종이의 아래쪽 변과 도화지의 아래쪽 변 사이의 거리이다. 색종이의 수는 100이하이며, 색종이가 도화지 밖으로 나가는 경우는 없다.
출력
첫째 줄에 색종이가 붙은 검은 영역의 둘레의 길이를 출력한다.
문제 풀이
구현 문제.
도화지가 100*100 크기이므로, boolean 타입의 2차원 배열을 만들고 색종이가 붙은 부분을 구분해주면 된다. 색종이를 붙인 위치는 정사각형 색종이의 왼쪽 하단이므로 해당 위치부터 시작하여 10*10 크기만큼 색종이가 붙었음을 표시한다. (해당 위치를 true로 변경.)
색종이가 있는 부분은 true이고, 그 색종이의 외곽선은 상하좌우 4개의 인접한 칸이 하나라도 false인 경우가 된다. 모서리 부분을 맡는 칸은 어느 두 칸이 인접하므로 얻게 되는 둘레는 2가 되고, 나머지는 1이 된다.
전체 탐색을 하며 칸이 true인 칸에 대해 false인 인접한 칸이 몇 개 있는지 확인하면 된다. 모서리 부분은 둘레가 2가 됨에 주의.
아래는 코드.
#include <iostream>
using namespace std;
bool** map;
int dx[] = { -1, 0, 0, 1 };
int dy[] = { 0, -1, 1, 0 };
int countBorder(int i, int j)
{
int count = 0;
for (int k = 0; k < 4; k++)
{
int nextX = i + dx[k];
int nextY = j + dy[k];
if ((nextX < 0 || nextY < 0 || nextX >= 100 || nextY >= 100) || map[nextX][nextY] == false)
{
count++;
}
}
return count;
}
int main()
{
cin.tie(NULL);
ios::sync_with_stdio(false);
map = new bool*[101];
int answer = 0;
for (int i = 0; i < 101; i++)
{
map[i] = new bool[101];
for (int j = 0; j < 101; j++)
{
map[i][j]=false;
}
}
int N, x, y;
cin >> N;
for (int i = 0; i < N; i++)
{
cin >> x >> y;
for (int j = x; j < x + 10; j++)
{
for (int k = y; k < y + 10; k++)
{
map[j][k] = true;
}
}
}
for (int i = 0; i < 101; i++)
{
for (int j = 0; j < 101; j++)
{
if (map[i][j] == true)
{
answer += countBorder(i, j);
}
}
}
cout << answer << "\n";
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준 3020] 개똥벌레 (C++) (0) | 2024.10.17 |
---|---|
[백준 17479] 정식당 (C++) (0) | 2024.10.16 |
[백준 2331] 반복수열 (C++) (0) | 2024.10.14 |
[백준 13335] 트럭 (C++) (0) | 2024.10.13 |
[백준 2628] 종이자르기 (C++) (0) | 2024.10.12 |