🙇‍♀️[Silver V] 직사각형 네개의 합집합의 면적 구하기 - 2669

문제 링크

성능 요약

메모리: 2176 KB, 시간: 0 ms

분류

구현

제출 일자

2023년 12월 26일 14:28:40

문제 설명

평면에 네 개의 직사각형이 놓여 있는데 그 밑변은 모두 가로축에 평행하다. 이 네 개의 직사각형들은 서로 떨어져 있을 수도 있고, 겹쳐 있을 수도 있고, 하나가 다른 하나를 포함할 수도 있으며, 변이나 꼭짓점이 겹칠 수도 있다.

이 직사각형들이 차지하는 면적을 구하는 프로그램을 작성하시오.

입력

입력은 네 줄이며, 각 줄은 직사각형의 위치를 나타내는 네 개의 정수로 주어진다. 첫 번째와 두 번째의 정수는 사각형의 왼쪽 아래 꼭짓점의 x좌표, y좌표이고 세 번째와 네 번째의 정수는 사각형의 오른쪽 위 꼭짓점의 x좌표, y좌표이다. 모든 x좌표와 y좌표는 1이상이고 100이하인 정수이다.

출력

첫 줄에 네개의 직사각형이 차지하는 면적을 출력한다.

🚀풀이

처음에는 교집합을 생각하지 않고 모든 사각형의 넓이를 구한뒤, 교집합의 넓이를 구하고 빼려했다.

교집합이 될 수 있는 경우를 구하고 교집합의 모양을 생각해서 문제를 풀려고하니까 많이 복잡해졌다.

총 4개의 사각형 중에 교집합을 다 생각하려면 3!의 경우의 수가 나온다.

뿐만아니라 하나의 경우에도 교집합의 모양이 크게 4개로 나뉘어지는데 이 방법은 아닌거같아서 포기했다.

그럼 처음부터 교집합을 계산하지 않거나 더 빠른 방법이 있다고 유추할 수가 있는데

교집합을 생각안하는 방법으로 visited 방법을 썼다.

일단 색칠하면 다음에는 계산안하는 방식이다.

그 코드는 다음과 같다.

int board[200][200];
int res = 0;

void solve()
{
	for (int i = 0; i < 4; ++i)
	{
		int x1, y1, x2, y2;
		cin >> x1 >> y1 >> x2 >> y2;
		for (int y = y1; y < y2; ++y)
		{
			for (int x = x1; x < x2; ++x)
			{
				if (board[y][x] == 0)
				{
					res++;
					board[y][x] = 1;
				}
			}
		}
	}

	cout << res;
}

입력이 들어오면 그 구간은 모두 색칙을 시작하는데 이때 첫 색칠을 한 경우에만 결과값을 갱신시켜준다.

나중에 다른 사각형을 그릴때는 중복되게 그릴때 갱신을 자동적으로 안하게 된다.

🚀전체 코드

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include<iostream>
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

int board[200][200];
int res = 0;

void solve()
{
	for (int i = 0; i < 4; ++i)
	{
		int x1, y1, x2, y2;
		cin >> x1 >> y1 >> x2 >> y2;
		for (int y = y1; y < y2; ++y)
		{
			for (int x = x1; x < x2; ++x)
			{
				if (board[y][x] == 0)
				{
					res++;
					board[y][x] = 1;
				}
			}
		}
	}

	cout << res;
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	freopen("input.txt", "rt", stdin);

	solve();

	return 0;
}