17387(선분 교차2)

2023. 3. 5. 21:19·Baekjoon/기하학

난이도: 골드 2

 

https://www.acmicpc.net/problem/17387

 

17387번: 선분 교차 2

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

www.acmicpc.net

 

문제

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,000,000 ≤ x1, y1, x2, y2, x3, y3, x4, y4 ≤ 1,000,000
  • x1, y1, x2, y2, x3, y3, x4, y4는 정수
  • 선분의 길이는 0보다 크다.

풀이

#include <iostream>
#include <algorithm>
using namespace std;

struct Point {
    double x, y;
    Point() {}
    Point(double x, double y) : x(x), y(y) {}
    Point operator - (const Point& a) const {
        return Point(x - a.x, y - a.y);
    }
    double operator * (const Point& a) const {
        return x * a.y - y * a.x;
    }
    bool operator > (const Point& a) const {
        if (x != a.x)
            return x > a.x;
        return y > a.y;
    }
    bool operator <= (const Point& a) const {
        if (x != a.x)
            return x < a.x;
        return y <= a.y;
    }
};

int ccw(Point p1, Point p2, Point p3) {
    double res = (p2 - p1) * (p3 - p2);
    if (res > 0) return 1; // 반시계 방향
    else if (res < 0) return -1; // 시계 방향
    else return 0; // 일직선
}

bool isIntersect(Point p1, Point p2, Point p3, Point p4) {
    // 선분이 교차하려면,
    // (한 선분에서 다른 선분의 점으로 ccw를 할 때 하나는 좌회전, 다른 하나는 우회전을 해야 함)
    // ccw(p1, p2, p3) * ccw(p1, p2 ,p4) 음수 
    // ccw(p3, p4, p1) * ccw(p3, p4, p2) 음수
    int ccw1 = ccw(p1, p2, p3) * ccw(p1, p2, p4);
    int ccw2 = ccw(p3, p4, p1) * ccw(p3, p4, p2);
    if (ccw1 == 0 && ccw2 == 0) {   
        // 직선상에 놓여있을 때, 점이 겹치거나 선분 위에 있는지 체크
        if (p1 > p2) swap(p1, p2);
        if (p3 > p4) swap(p3, p4);
        return p3 <= p2 && p1 <= p4;
    }
    return ccw1 <= 0 && ccw2 <= 0;
}

int main() {
    Point p1, p2, p3, p4;
    cin >> p1.x >> p1.y >> p2.x >> p2.y >> p3.x >> p3.y >> p4.x >> p4.y;

    cout << isIntersect(p1, p2, p3, p4);
}

 

'Baekjoon > 기하학' 카테고리의 다른 글

10216(Count Circle Groups)  (0) 2023.03.07
2162(선분 그룹)  (0) 2023.03.05
1358(하키)  (0) 2023.03.02
1708(볼록 껍질)  (0) 2023.03.02
2261(가장 가까운 두 점)  (0) 2023.02.28
'Baekjoon/기하학' 카테고리의 다른 글
  • 10216(Count Circle Groups)
  • 2162(선분 그룹)
  • 1358(하키)
  • 1708(볼록 껍질)
KimMK
KimMK
  • KimMK
    KimMK
    KimMK
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Unreal
      • Git
      • C++
        • 디자인 패턴
        • STL
      • 자료구조 & 알고리즘
      • Portfolio
        • Unreal C
        • Unreal BP
      • Baekjoon
        • 분할정복
        • BFS(너비우선탐색)
        • DFS(깊이우선탐색)
        • 탐욕(Greedy)
        • 동적계획법(DP)
        • 기하학
        • 백트래킹
        • 트리
        • 구현
      • Portfolio 개발 진행중
        • 개발 진행 중
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Queue
    리플렉션
    유니온-파인드
    디자인패턴
    경량 패턴
    비교 기반 정렬 알고리즘
    Set
    자료구조
    동적 계획법
    Unreal Collision
    트리
    Factory method pattern
    unreal insight
    스택
    분포 기반 정렬 알고리즘
    Abstract Factory pattern
    관찰자(Observer) 패턴
    object channel
    명령패턴
    Union-Find
    생성패턴
    언리얼 프로퍼티 시스템
    두 직선사이 교점
    트리순회
    flyweight pattern
    BFS
    C++ STL 정리
    깊이 우선 탐색
    command pattern
    Trie
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
KimMK
17387(선분 교차2)
상단으로

티스토리툴바