Plite
전자오락 공방
Plite
전체 방문자
오늘
어제
  • 분류 전체보기 (274)
    • 프로젝트 (18)
      • 완성 프로젝트 (3)
      • 프로젝트 진행 내역 (15)
    • 공부 및 정리 (241)
      • 백준 코드 (222)
      • C++ (8)
      • DirectX (2)
      • Unreal Engine (6)
      • 프로그래밍 패턴 (3)
    • 기타 (12)
      • 기타 주저리 (10)
    • 게임과 취미 (1)
    • 대문 (1)

블로그 메뉴

  • 홈
  • 프로젝트
  • 취미, 일상
  • 백준 프로필

공지사항

  • [Read Me]
  • 제 블로그에 방문하신 것을 환영합니다.

인기 글

태그

  • 동적계획법
  • 백준
  • 백트래킹
  • 최소 스패닝 트리
  • 정수론
  • 구현
  • 트리
  • 브루트포스
  • 위상 정렬
  • 정렬
  • 수학
  • 세그먼트 트리
  • 분할정복
  • 스택
  • KMP
  • 조합론
  • 우선순위큐
  • 이분탐색
  • C++
  • LCA
  • 트라이
  • 그래프
  • 누적합
  • 큐
  • SCC
  • 유니온 파인드
  • 기하
  • 문자열
  • UC++
  • 투포인터

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Plite

전자오락 공방

[C++]백준 - 17387번 문제
공부 및 정리/백준 코드

[C++]백준 - 17387번 문제

2021. 10. 22. 18:15

17387번: 선분 교차 2 (acmicpc.net)

 

17387번: 선분 교차 2

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

www.acmicpc.net

 

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가 주어진다.

  • -1,000,000 ≤ x1, y1, x2, y2, x3, y3, x4, y4 ≤ 1,000,000
  • x1, y1, x2, y2, x3, y3, x4, y4는 정수

 

 

출력


L1과 L2가 교차하면 1, 아니면 0을 출력한다.

 

 


 

생각해 볼 점


CCW 알고리즘을 활용해서 선분이 교차했는지 알아봅니다.

 

CCW 알고리즘은 반시계 방향(Counter-Clock-Wise)의 줄임말로, 세 점이 주어졌을 때

 

세 점이 반시계 방향으로 나아가고 있는 지 확인하는 알고리즘입니다.

 

 

 

점 3개의 방향성을 나타내는 CCW (acmicpc.net)

 

점 3개의 방향성을 나타내는 CCW

세 점 P1(x1, y1), P2(x2, y2), P3(x3, y3)가 있을 떄, 점 3개를 이은 선분은 어떤 방향성을 나타내게 될까요? 11758번 문제: CCW 가능한 경우의 수는 총 3가지가 있습니다. 반시계 방향, 시계 방향, 일직선. 시

www.acmicpc.net

 

더 자세한 내용은 위 링크에서 확인할 수 있습니다. 

 

 

두 선분이 교차하는 지 알려면 CCW 알고리즘을 총 4번 사용해야 합니다.

 

1. CCW(1, 2, 3) * CCW(1, 2, 4)

2. CCW(3, 4, 1) * CCW(3, 4, 2)

 

그리고 1번과 2번 값이 모두 0보다 작아야 선분이 교차합니다.

 

그렇지 않으면, 아래 그림처럼 선분이 교차하지 않습니다.

 

 

 

또한, 아래 그림과 같은 경우 역시 주의해야합니다.

선분 두 개가 평행하지만, 교차하지는 않습니다. 하지만 1~2번 선분이 조금만 더 길었다면 교차할 수도 있습니다.

 

CCW 알고리즘 4개를 구하더라도 모두 0인 경우입니다. 이 경우는 따로 예외처리를 해서,

 

두 선분이 교차하는지 구해야 합니다.

 

코드


#include <iostream>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> Point;
#define swap(A, B) {Point temp; temp = A; A = B; B = temp;}

//CCW 알고리즘
int ccw(Point A, Point B, Point C)
{
    ll temp1 = A.first * B.second + B.first * C.second + C.first * A.second;
    ll temp2 = A.second * B.first + B.second * C.first + C.second * A.first;
    ll result = temp1 - temp2;
    
    if(result < 0) return -1;
    else if(result == 0) return 0;
    else return 1;
}

//판정
bool is_crossed(Point P1, Point P2, Point P3, Point P4)
{
    int ccw1 = ccw(P1, P2, P3);
    int ccw2 = ccw(P2, P3, P4);
    int ccw3 = ccw(P3, P4, P1);
    int ccw4 = ccw(P4, P1, P2);

    bool is_crossed;
    
    //직선일 때
    if(ccw1 * ccw4 == 0 && ccw2 * ccw3 == 0)
    {
        if(P2 < P1) swap(P1, P2);
        if(P4 < P3) swap(P3, P4);

        //겹쳤으면
        if(P1 <= P4 && P3 <= P2) return true;
        else return false;
    }
    
    return ccw1 * ccw4 <= 0 && ccw2 * ccw3 <= 0;
}

int main() 
{
    Point P1, P2, P3, P4;
    
    cin >> P1.first >> P1.second >> P2.first >> P2.second;
    cin >> P3.first >> P3.second >> P4.first >> P4.second;
    
    if(is_crossed(P1, P2, P3, P4)) cout << 1;
    else cout << 0;
    
	return 0;
}

 

그 외


 

저작자표시

'공부 및 정리 > 백준 코드' 카테고리의 다른 글

[C++]백준 - 11779번 문제  (0) 2021.10.23
[C++]백준 - 18111번 문제  (0) 2021.10.22
[C++]백준 - 17386번 문제  (0) 2021.10.20
[C++]백준 - 9372번 문제  (0) 2021.10.20
[C++]백준 - 9019번 문제  (0) 2021.10.19
    '공부 및 정리/백준 코드' 카테고리의 다른 글
    • [C++]백준 - 11779번 문제
    • [C++]백준 - 18111번 문제
    • [C++]백준 - 17386번 문제
    • [C++]백준 - 9372번 문제
    Plite
    Plite
    개발 일지, 게임 이야기 등을 적어두는 공간입니다.

    티스토리툴바