Post

[백준 C++] 17387번 선분 교차 2

백준 17387번 선분 교차 2 c++로 풀이

[백준 C++] 17387번 선분 교차 2

17387번: 선분 교차 2

문제 요약

문제

2차원 좌표 평면 위의 두 선분 L1, L2가 주어졌을 때, 두 선분이 교차하는지 아닌지 구해보자. 한 선분의 끝 점이 다른 선분이나 끝 점 위에 있는 것도 교차하는 것이다.

L1의 양 끝 점은 (x1, y1), (x2, y2), L2의 양 끝 점은 (x3, y3), (x4, y4)이다.

사용 알고리즘

기하학

입출력

  • 입력: 첫째 줄에 L1의 양 끝 점 x1, y1, x2, y2가, 둘째 줄에 L2의 양 끝 점 x3, y3, x4, y4가 주어진다.
  • 출력: L1과 L2가 교차하면 1, 아니면 0을 출력한다. ``` 예제1

입력 1 1 5 5 1 5 5 1 출력 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
## 풀이
CCW 를 활용하는 문제이다. 한 선분에서 다른 두개의 점이 각각 시계방향과 반시계방향으로 나눠져 있으면 그 선분을 교차한다. 이는 반대쪽에서도 만족해야 성립한다

## 어려웠던 점


## 배운 점 / 느낀 점


## 전체 코드
```cpp
#include <iostream>
#include <algorithm>
using namespace std;

struct Point {
    int x, y;
};

int ccw(Point a, Point b, Point c) {
    long long val = 1LL * (b.x - a.x) * (c.y - a.y) 
                  - 1LL * (b.y - a.y) * (c.x - a.x);
    if (val > 0) return 1;     // 반시계 방향
    if (val < 0) return -1;    // 시계 방향
    return 0;                  // 일직선
}

bool isCross(Point a, Point b, Point c, Point d) {
    int ab = ccw(a, b, c) * ccw(a, b, d);
    int cd = ccw(c, d, a) * ccw(c, d, b);

    if (ab == 0 && cd == 0) {
        // 두 선분이 일직선상에 있을 때는 범위 겹침 여부로 판단
        if (a.x > b.x) swap(a, b);
        if (c.x > d.x) swap(c, d);
        return !(b.x < c.x || d.x < a.x || max(a.y, b.y) < min(c.y, d.y) || max(c.y, d.y) < min(a.y, b.y));
    }

    return ab <= 0 && cd <= 0;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    Point A, B, C, D;
    cin >> A.x >> A.y >> B.x >> B.y;
    cin >> C.x >> C.y >> D.x >> D.y;

    cout << (isCross(A, B, C, D) ? 1 : 0);
    return 0;
}
This post is licensed under CC BY 4.0 by the author.