득이공간

[백준 C++] 17387 선분 교차 2 - 많은조건분기 본문

PS/알고리즘 문제풀이

[백준 C++] 17387 선분 교차 2 - 많은조건분기

쟁득 2024. 4. 5. 21:15

 

17387번: 선분 교차 2

첫째 줄에 L1의 양 끝 점 x1, y1, x2, y2가, 둘째 줄에 L2의 양 끝 점 x3, y3, x4, y4가 주어진다.

www.acmicpc.net


 

문제풀이

 

기하학 & 많은 조건 분기 유형의 문제입니다.

두 선분이 교차하는 세 가지 경우를 체크해서 풀었습니다.

 

1. (양쪽 선분 모두) 현재 선분을 기준으로 상대 선분의 두 점이 좌우 양쪽에 위치하는 경우

2. 상대 선분의 한 점이 현재 선분을 기준으로 동일선상에 위치하고 상대 선분은 1번 조건에 해당하는 경우

3. (양쪽 선분 모두) 상대 선분의 한 점이 현재 선분을 기준으로 동일선상에 위치하는 경우

3-a. 두 선분이 같은 일직선 상에 존재하므로 네 점의 좌표 비교를 통해 두 선분이 겹치는지 판별

 

이 경우들을 두 벡터의 외적을 통해 값을 구하는 CCW 알고리즘을 이용해서 판별하도록 구현했습니다.


참고자료

 

CCW(counter clockwise)

gaussian37's blog

gaussian37.github.io

 

선분의 교차 여부 확인

gaussian37's blog

gaussian37.github.io


코드

cpp
#include <iostream> using namespace std; typedef long long ll; typedef pair<ll, ll> point; ll X1, Y1, X2, Y2, X3, Y3, X4, Y4; point P1, P2, P3, P4; ll CCW(point A, point B, point C) { ‌ll Result = (B.first - A.first) * (C.second - A.second); ‌Result -= (C.first - A.first) * (B.second - A.second); if (Result > 0) { ‌‌return 1; } else if (Result < 0) { ‌‌return -1; } return 0; } bool Intersect() { ‌ll C1 = CCW(P1, P2, P3); ‌ll C2 = CCW(P1, P2, P4); ‌ll C3 = CCW(P3, P4, P1); ‌ll C4 = CCW(P3, P4, P2); ‌ll Con1 = C1 * C2; ‌ll Con2 = C3 * C4; if (Con1 < 0 && Con2 < 0) { ‌‌return true; } else if ((Con1 == 0 && Con2 < 0) ‌‌‌|| (Con1 < 0 && Con2 == 0) ‌‌‌|| ((Con1 == 0 && Con2 == 0) && (C1 != 0 || C2 != 0) && (C3 != 0 || C4 != 0))) { ‌‌return true; } else if (C1 == 0 && C2 == 0 && C3 == 0 && C4 == 0) { ‌‌if (X1 == X2) ‌‌{ ‌‌‌if (Y1 < Y2 && Y3 < Y4 ‌‌‌‌&& Y3 <= Y2 && Y1 <= Y4) ‌‌‌{ ‌‌‌‌return true; ‌‌‌} ‌‌‌else if (Y1 < Y2 && Y3 > Y4 ‌‌‌‌&& Y4 <= Y2 && Y1 <= Y3) ‌‌‌{ ‌‌‌‌return true; ‌‌‌} ‌‌‌else if (Y1 > Y2 && Y3 < Y4 ‌‌‌‌&& Y3 <= Y1 && Y2 <= Y4) ‌‌‌{ ‌‌‌‌return true; ‌‌‌} ‌‌‌else if (Y1 > Y2 && Y3 > Y4 ‌‌‌‌&& Y4 <= Y1 && Y2 <= Y3) ‌‌‌{ ‌‌‌‌return true; ‌‌‌} ‌‌} ‌‌else if (X1 < X2 && X3 < X4 ‌‌‌‌&& X3 <= X2 && X1 <= X4) ‌‌{ ‌‌‌return true; ‌‌} ‌‌else if (X1 < X2 && X3 > X4 ‌‌‌‌&& X4 <= X2 && X1 <= X3) ‌‌{ ‌‌‌return true; ‌‌} ‌‌else if (X1 > X2 && X3 < X4 ‌‌‌‌&& X3 <= X1 && X2 <= X4) ‌‌{ ‌‌‌return true; ‌‌} ‌‌else if (X1 > X2 && X3 > X4 ‌‌‌‌&& X4 <= X1 && X2 <= X3) ‌‌{ ‌‌‌return true; ‌‌} } return false; } int main() { ‌ios::sync_with_stdio(false); ‌cin.tie(nullptr); cout.tie(nullptr); ‌cin >> X1 >> Y1 >> X2 >> Y2; ‌cin >> X3 >> Y3 >> X4 >> Y4; ‌P1.first = X1; ‌P1.second = Y1; ‌P2.first = X2; ‌P2.second = Y2; ‌P3.first = X3; ‌P3.second = Y3; ‌P4.first = X4; ‌P4.second = Y4; ‌cout << Intersect(); }