※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 13352번 문제인 석양이 진다...이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/13352
각각의 적이 있는 좌표를 점이라 하자.
점이 4개 이하이면 두 점을 잇는 두 직선을 그어 모든 점이 두 직선 위에 올라가있게 할 수 있다. 또한, 모든 점이 두 직선 위에 올라가있을 수 있다면, 5개의 점 중 적어도 세 개의 점은 같은 직선 위에 있어야 한다.(비둘기집의 원리)
따라서 주어진 점이 5개 이상인 경우, 다섯 개의 점을 골라 점을 적어도 3개 포함하는 직선을 찾고(없다면 "failure" 출력), 그 직선 위에 있지 않은 모든 점이 한 직선 위에 있는지를 확인해 문제를 해결하자.
아래는 제출한 소스코드이다.
#include <iostream>
#include <cassert>
using namespace std;
typedef long long ll;
int gcd(int x, int y) {
if (y) return gcd(y, x % y);
return x;
}
int N, M;
int A[100000][2];
int pp = -1, qq = -1, rr = -1;
int visited[100000];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N;
if (N <= 4) {
cout << "success";
return 0;
}
for (int i = 0; i < N; i++) cin >> A[i][0] >> A[i][1];
for (int i = 0; i < 5; i++) {
for (int j = i + 1; j < 5; j++) {
for (int k = j + 1; k < 5; k++) {
int dx1 = A[i][0] - A[j][0], dy1 = A[i][1] - A[j][1];
int dx2 = A[j][0] - A[k][0], dy2 = A[j][1] - A[k][1];
int g1 = gcd(abs(dx1), abs(dy1)), g2 = gcd(abs(dx2), abs(dy2));
dx1 /= g1, dy1 /= g1, dx2 /= g2, dy2 /= g2;
if (dx1 < 0) dx1 *= -1, dy1 *= -1;
else if (!dx1) dy1 = 1;
if (dx2 < 0) dx2 *= -1, dy2 *= -1;
else if (!dx2) dy2 = 1;
if (dx1 == dx2 && dy1 == dy2) {
pp = i, qq = j, rr = k;
}
}
}
}
if (pp < 0) {
cout << "failure";
return 0;
}
visited[pp] = visited[qq] = 1;
for (int k = 0; k < N; k++) {
if (k == pp || k == qq) continue;
int i = pp, j = qq;
int dx1 = A[i][0] - A[j][0], dy1 = A[i][1] - A[j][1];
int dx2 = A[j][0] - A[k][0], dy2 = A[j][1] - A[k][1];
int g1 = gcd(abs(dx1), abs(dy1)), g2 = gcd(abs(dx2), abs(dy2));
dx1 /= g1, dy1 /= g1, dx2 /= g2, dy2 /= g2;
if (dx1 < 0) dx1 *= -1, dy1 *= -1;
else if (!dx1) dy1 = 1;
if (dx2 < 0) dx2 *= -1, dy2 *= -1;
else if (!dx2) dy2 = 1;
if (dx1 == dx2 && dy1 == dy2) visited[k] = 1;
}
for (int i = 0; i < N; i++) {
if (!visited[i]) {
A[M][0] = A[i][0], A[M][1] = A[i][1];
M++;
}
}
for (int j = 1; j + 1 < M; j++) {
int i = j - 1, k = j + 1;
int dx1 = A[i][0] - A[j][0], dy1 = A[i][1] - A[j][1];
int dx2 = A[j][0] - A[k][0], dy2 = A[j][1] - A[k][1];
int g1 = gcd(abs(dx1), abs(dy1)), g2 = gcd(abs(dx2), abs(dy2));
dx1 /= g1, dy1 /= g1, dx2 /= g2, dy2 /= g2;
if (dx1 < 0) dx1 *= -1, dy1 *= -1;
else if (!dx1) dy1 = 1;
if (dx2 < 0) dx2 *= -1, dy2 *= -1;
else if (!dx2) dy2 = 1;
if (dx1 != dx2 || dy1 != dy2) {
cout << "failure";
return 0;
}
}
cout << "success";
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 7587 // C++] Anagrams (0) | 2024.06.24 |
---|---|
[BOJ 27738 // C++] 연산자 파티 (0) | 2024.06.23 |
[BOJ 2187 // C++] 점 고르기 (0) | 2024.06.21 |
[BOJ 3688 // C++] 래프팅 디자인 (0) | 2024.06.20 |
[BOJ 22683 // C++] Square Route (1) | 2024.06.19 |