BOJ 2669. 직사각형 네개의 합집합의 면적 구하기
🙇♀️[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;
}