선분 교차 2(백준_17387)

2023. 2. 18. 02:00·BackEnd/알고리즘 공부

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

 

17387번: 선분 교차 2

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

www.acmicpc.net

 

문제 설명

선분 L1, L2가 주어졌을 때, 두 선분이 교차하는지 구하는 문제이다. 이 때, 두 선분이 겹쳐도 교차하는 것이라고 생각한다.

 

문제에 대한 아이디어

이 문제를 풀기위해서는 CCW라는 알고리즘을 알고 있어야 한다. CCW는 평면상의 3개의 점과 관련된 점들의 위치 관계를 판단하는 알고리즘이다. 3개의 점을 A(X1, Y1) B(X2, Y2) C(X3, Y3) 라고 하자.

CCW = (X1Y2 + X2Y3 + X3Y1) - (X2Y1 + X3Y2 + X1Y3) 이다. 이 결과의 절댓값은 세 점의 백터의 외적값을 나타낸다,

  • CCW < 0 : 시계 방향으로 이동
  • CCW = 0 : 일직선
  • CCW > 0 : 반시계 방향으로 이동

참고로 CCW 절댓값의 절반은 삼각형의 넓이이다.

 

CCW를 이용하여 문제풀기

선분이 교차 할 경우 3개의 점에서 CCW를 구하면 부호가 반대일 것이다.

그러므로 각각 CCW의 곱이 음수일 것이다.

반대로 교차를 안하게 되면 CCW의 값은 양수라는 것을 알 수 있다.

만약 일직선일 경우는 CCW의 값은 0일 것이다.

이때, 두 직선이 겹치는 지를 확인해야 한다.

이렇게 겹치게 되면 알 수 있는 것은 한점의 선분 AB의 x Max 값이 선분 CD의 x Min 값보다 크다는 것이다. 그러므로 모든 점을 각각 조사해 겹치는지 확인해보면 된다.

 

구현

  • CCW
static int CCW(long x1, long y1, long x2, long y2, long x3, long y3){
    long temp = (x1 * y2 + x2 * y3 + x3 * y1) - (x2 * y1 + x3 * y2 + x1 * y3);
    if(temp > 0) return 1;
    else if(temp < 0) return -1;
    return 0;
}
  • isOverlab(겹치는지 검사)
private static boolean isOverlab(long x1, long y1, long x2, long y2, long x3, long y3, long x4, long y4){
    if(Math.min(x1, x2) <= Math.max(x3, x4) && Math.min(x3, x4) <= Math.max(x1, x2) && Math.min(y1, y2) <= Math.max(y3, y4) && Math.min(y3, y4) <= Math.max(y1,y2)) return true;
    return false;
}
  • isCross
private static boolean isCross(long x1, long y1, long x2, long y2, long x3, long y3, long x4, long y4){
    int abc = CCW(x1,y1,x2,y2,x3,y3);
    int abd = CCW(x1,y1,x2,y2,x4,y4);
    int cda = CCW(x3,y3,x4,y4,x1,y1);
    int cdb = CCW(x3,y3,x4,y4,x2,y2);
    //일직선일 경우 겹치는지 검사
    if(abc * abd == 0 && cda * cdb == 0){
        return isOverlab(x1,y1,x2,y2,x3,y3,x4,y4);
    }else if(abc*abd <= 0 && cda * cdb <= 0) {return true;}
    return false;
}
  • Main
public static void main(String []args) throws IOException {
    BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st;
    st = new StringTokenizer(buf.readLine());
    long x1 = Integer.parseInt(st.nextToken());
    long y1 = Integer.parseInt(st.nextToken());
    long x2 = Integer.parseInt(st.nextToken());
    long y2 = Integer.parseInt(st.nextToken());
    st = new StringTokenizer(buf.readLine());
    long x3 = Integer.parseInt(st.nextToken());
    long y3 = Integer.parseInt(st.nextToken());
    long x4 = Integer.parseInt(st.nextToken());
    long y4 = Integer.parseInt(st.nextToken());
    boolean cross = isCross(x1,y1,x2,y2,x3,y3,x4,y4);
    if (cross) System.out.println(1);
    else System.out.println(0);

}

https://github.com/Heron-Woong/CodingTest_Practice/blob/main/%EB%B0%B1%EC%A4%80_17387.java

 

GitHub - Heron-Woong/CodingTest_Practice

Contribute to Heron-Woong/CodingTest_Practice development by creating an account on GitHub.

github.com

 

'BackEnd > 알고리즘 공부' 카테고리의 다른 글

운동(백준_1956)  (0) 2023.02.22
사회망 서비스(SNS)(백준_2533)  (0) 2023.02.19
가장 긴 증가하는 부분 수열 5(백준_14003)  (0) 2023.02.15
욕심쟁이 판다(백준_1937)  (0) 2023.02.14
외판원 순회(백준_2098)  (0) 2023.02.13
'BackEnd/알고리즘 공부' 카테고리의 다른 글
  • 운동(백준_1956)
  • 사회망 서비스(SNS)(백준_2533)
  • 가장 긴 증가하는 부분 수열 5(백준_14003)
  • 욕심쟁이 판다(백준_1937)
인프라 감자
인프라 감자
  • 인프라 감자
    삶은 인프라
    인프라 감자
  • 전체
    오늘
    어제
    • 분류 전체보기 (243)
      • 클라우드&인프라 (28)
        • 인프라 공부 (4)
        • AWS 구조와 서비스 (18)
        • 클라우드 공부 (4)
        • Terraform (2)
      • AWS Cloud School (13)
        • project (5)
        • Linux, Network (6)
        • Docker (2)
      • BackEnd (162)
        • JAVA 공부 (15)
        • 알고리즘 공부 (71)
        • MySQL 문제 풀기 (8)
        • 스프링 핵심 원리 - 기본편 (18)
        • 스프링 MVC 1편 (4)
        • 자바 ORM 표준 JPA 프로그래밍 (21)
        • 실전! 스프링 부트와 JPA 활용1 (8)
        • 실전! 스프링 부트와 JPA 활용2 (5)
        • 스프링 데이터 JPA (8)
        • Querydsl (4)
      • 혼자하는 프로젝트 (32)
        • 배달의 민족 클론코딩 (7)
        • 나만의 프로젝트 (10)
        • 스프링 부트로 구현한 웹 (15)
  • 블로그 메뉴

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

    • Email
    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    유니온 파인드
    이것이 자바다
    다이나믹 프로그래밍
    상속
    스프링 핵심 원리-기본편
    VPN
    조합
    querydsl
    네트워크 기본 용어
    dp
    디팬스 게임
    프로그래머스
    완전탐색
    정렬
    자동 배포
    쿼드 압축
    백트래킹
    linux
    자바
    중첩 선언
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
인프라 감자
선분 교차 2(백준_17387)
상단으로

티스토리툴바