※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 2700번 문제인 볼록 격자 다각형의 내부점이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/2700
2700번: 볼록 격자 다각형의 내부점
첫 줄에는 수평선의 개수를 출력한다. 만약, 수평선이 하나 이상 있다면, 수평선의 y 좌표 값을 한 줄에 하나씩 출력한다. 이때 y좌표 내림차순으로 출력한다. 각각의 y좌표 값 뒤에 공백을 사이
www.acmicpc.net
볼록다각형의 내부에 점이 있는지 확인하는 가장 쉬운 방법은 다각형을 일정한 방향으로 돌면서 각 변과 점 사이의 CCW의 값을 확인하는 것이다. 점이 다각형의 내부에 있다면 CCW의 값은 전부 1로 통일되어있거나 -1로 통일되어있을 것이라는 점을 관찰하자.
주어지는 좌표의 범위가 매우 작다는 점을 이용해서, 각 테스트케이스마다 x와 y가 각각 -30 이상 30 이하인 모든 점(61*61=3721개)에 대해 각 점이 주어진 다각형의 내부에 있는지를 테스트하는 것으로 문제를 해결할 수 있다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
using namespace std;
int N;
pair<int, int> points[51];
int CCW(pair<int, int>& p1, pair<int, int>& p2, pair<int, int>& p3) {
int ccw = (p2.first - p1.first) * (p3.second - p1.second) - (p2.second - p1.second) * (p3.first - p1.first);
if (ccw > 0) return 1;
else return 0;
}
void solve() {
vector<int> ans[61];
int anscnt = 0;
cin >> N;
for (int i = 0; i < N; i++) cin >> points[i].first >> points[i].second;
points[N] = points[0];
for (int y = -29; y < 30; y++) {
for (int x = -29; x < 30; x++) {
pair<int, int> cur = make_pair(x, y);
int cnt = 0;
for (int i = 0; i < N; i++) {
cnt += CCW(points[i], cur, points[i + 1]);
}
if (cnt < N) continue;
ans[y + 30].emplace_back(x);
}
}
for (int y = 1; y < 60; y++) {
if (!ans[y].empty()) anscnt++;
}
cout << anscnt << '\n';
for (int y = 59; y > 0; y--) {
if (!ans[y].empty()) {
cout << y - 30 << ' ' << ans[y].front() << ' ' << ans[y].back() << '\n';
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int T; cin >> T;
while (T--) solve();
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 2693 // C++] N번째 큰 수 (0) | 2023.04.25 |
---|---|
[BOJ 2701 // C++] 육각 퍼즐 (0) | 2023.04.24 |
[BOJ 2698 // C++] 인접한 비트의 개수 (0) | 2023.04.22 |
[BOJ 2697 // C++] 다음수 구하기 (0) | 2023.04.21 |
[BOJ 2694 // C++] 합이 같은 구간 (0) | 2023.04.20 |