10163번: 색종이

평면에 색깔이 서로 다른 직사각형 모양의 색종이 N장이 하나씩 차례로 놓여진다. 이때 색종이가 비스듬하게 놓이는 경우는 없다. 즉, 모든 색종이의 변은 서로 평행하거나, 서로 수직이거나 둘

www.acmicpc.net

문제를 설계하면서 풀어보는 습관을 들여보기로 했다.

 

문제

 N장의 색종이가 주어진 위치에 차례로 놓일 경우, 각 색종이가 보이는 부분의 면적을 구해라.

 

입력

 1. 색종이 개수 (1 <= N <= 100)

 2. 평면격자 사이즈 101 x 101

 3. 격자 한 칸의 넓이 = 1 (정사각형임. 가로1, 세로1)

 

출력

 1. 각 색종이가 보이는 부분을 출력해라.

 2. 색종이가 보이지 않는다면 정수 0을 출력한다.

 

각 입력과 출력에서 얻을 수 있는 것들을 요약하면 위와 같다.

 

이제 문제이해를 했으니, 이를 토대로 문제 풀이 설계를 해보면 다음과 같다.

 

1. 총 격자 크기만큼의 배열 생성

 

2. 생성된 배열에 색종이를 순서대로 넣기

 2.1 - 너비와 높이 반대로 적용되게 색종이 넣기

 2.2 - 색종이 번호 순서에 따라 배열에 내부 숫자 변해서 넣도록 만들기.

 

<색종이 그림>

이 그림을 우측으로 90도 돌렸을 때 일반적인 배열이 되기 때문에, 너비와 높이가 반대로 입력되게 만들었다.

 

3. 각 색종이의 면적 구하기

 3.1 - 색종이 번호와 같은 배열 내부 숫자찾기

 

4. 출력하기

 4.1 - 색종이가 보이지 않는다면 정수 0 출력

 

 

이 설계에 따른 풀이는 첫 번째 풀이는 이것과 같다.

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>

int main()
{
	int board[101][101] = {0};
	int confetti;
	int row, column, width, height;

	scanf("%d", &confetti);

	for (int i = 1; i < confetti + 1; i++) {
		scanf("%d %d %d %d", &row, &column, &height, &width); // 너비랑 높이 바꿔서 입력되게 만들었음.
		for (int j = 0; j < height; j++) {
			for (int k = 0; k < width; k++) {
				board[row][column+k] = i;
			}
			row++;
		}
	}

	int tocount = 1;
	int gat = 0;
	while(tocount < confetti + 1) {
		for (int i = 0; i < 101; i++) {
			for (int j = 0; j < 101; j++) {
				if (board[i][j] == tocount) gat++;
			}
		}
		printf("%d\n", gat);
		tocount++;
		gat = 0;
	}
	
	return 0;
}

 

문제는 풀렸지만, 면적을 출력하는 부분의 코드가 마음에 들지않는다. 다시 코드를 작성해보자.

 

그렇게 설계 부분에 새로운 내용이 추가되었다.

3. 각 색종이의 면적 구하기

 3.1 - 색종이 번호와 같은 배열 내부 숫자찾기

 3.2 - 색종이의 면적을 구하여 면적 저장배열에 색종이 번호에 맞게 저장시킨다.

 

바뀐사항에 따른 코드는 다음과 같다.

 

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>

int main()
{
	int board[101][101] = { 0 };
	int confetti;
	int row, column, width, height;
	int cnt[101] = { 0 };

	scanf("%d", &confetti);

	for (int i = 1; i < confetti + 1; i++) {
		scanf("%d %d %d %d", &row, &column, &height, &width); // 너비랑 높이 바꿔서 입력되게 만들었음.
		for (int j = 0; j < height; j++) {
			for (int k = 0; k < width; k++) {
				board[row][column+k] = i;
			}
			row++;
		}
	}

	for (int i = 0; i < 101; i++) {
		for (int j = 0; j < 101; j++) {
			cnt[board[i][j]]++; 
            // cnt[0][0]이 1일때 +1
            // cnt[0][1]이 1일때 +1 이런식으로 1번  색종이의 면적이 구해진다.
		}
	}

	for (int i = 1; i < confetti + 1; i++) {
		printf("%d\n", cnt[i]);
	}
	
	return 0;
}

 

앞으로 좀 더 열심히 해야지!