11758 CCW (기하학) [Gold V]
11758번: CCW (acmicpc.net) 이 문제는 CCW(Counter-Clockwise) 공식을 알고있는지 물어보는 문제입니다.이 공식을 이용하면 시계 반대방향으로 회전하는지 확인할 수 있습니다. CCW 공식은 아래와 같습니다.
flrjtwjrjt.tistory.com
두개의 점(x,y)으로 만들어진 선을 두개 입력 받아서
두 선이 교차 하는지 아닌지 체크하는 문제입니다.
CCW를 이용하면 쉽게 풀 수 있습니다.
풀이법
두 개의 선이 만약 교차 할 때의 경우를 생각해보겠습니다.
선 ㄱ과 ㄴ이 있다고 가정하고 ㄱ은 두개의 벡터 A, B ㄴ은 C, D로 이루어져 있다고 가정하겠습니다.
ㄱ과 ㄴ이 교차하는 상황에서 A,B, C와 A,B, D의 방향은 한쪽은 시계 방향, 한쪽은 반시계 방향으로 반대일 것입니다.
즉 CCW 공식으로 계산 후 두 값을 곱하면 무조건 음수가 나오는데 이것을 이용하면 쉽게 풀 수 있을 것 같습니다.
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std;
long v[4][2];
int CCW(long v1[2], long v2[2], long v3[2]);
bool isCross();
bool isOverlab();
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
std::cout.tie(NULL);
for (int i = 0; i < 4; i++)
{
int a, b;
cin >> a >> b;
v[i][0] = a;
v[i][1] = b;
}
int result = isCross() ? 1 : 0;
cout << result << "\n";
}
int CCW(long v1[2], long v2[2], long v3[2])
{
long result = (v1[0] * v2[1] + v2[0] * v3[1] + v3[0] * v1[1]) - (v1[0] * v3[1] + v2[0] * v1[1] + v3[0] * v2[1]);
return result > 0 ? 1 : result < 0 ? -1 : 0;
}
bool isOverlab()
{
if (min(v[0][0], v[1][0]) <= max(v[2][0], v[3][0]) && min(v[2][0], v[3][0]) <= max(v[0][0], v[1][0]))
{
if (min(v[0][1], v[1][1]) <= max(v[2][1], v[3][1]) && min(v[2][1], v[3][1]) <= max(v[0][1], v[1][1]))
return true;
}
return false;
}
bool isCross()
{
int abc = CCW(v[0], v[1], v[2]);
int abd = CCW(v[0], v[1], v[3]);
int cda = CCW(v[2], v[3], v[0]);
int cdb = CCW(v[2], v[3], v[1]);
if (abc * abd == 0 && cda * cdb == 0) {
return isOverlab();
}
else if (abc * abd <= 0 && cda * cdb <= 0)
return true;
else
return false;
}
LIST
'알고리즘 문제 > 백준' 카테고리의 다른 글
9663 N-Queen (백트래킹) [Gold IV] (0) | 2024.05.19 |
---|---|
2162 선분 그룹 (기하학) [Platinum V] (0) | 2024.05.18 |
11758 CCW (기하학) [Gold V] (0) | 2024.05.16 |
11049 행렬 곱셈 순서 (동적계획법) [Gold III] (0) | 2024.05.13 |
1915 가장 큰 정사각형 (동적계획법) [Gold IV] (0) | 2024.05.09 |