코테/백준

[백준/JAVA] 17387번: 선분 교차 2

imname1am 2023. 5. 18. 18:26
반응형

🔺 문제

 

17387번: 선분 교차 2

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

www.acmicpc.net

 

 

🔺 코드

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
53
54
55
56
57
58
59
60
61
import java.util.*;
import java.io.*;
 
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine()," ");
        
        // L₁
        long x1 = Integer.parseInt(st.nextToken());
        long y1 = Integer.parseInt(st.nextToken());
        long x2 = Integer.parseInt(st.nextToken());
        long y2 = Integer.parseInt(st.nextToken());
        
        // L₂
        st = new StringTokenizer(br.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);
    }
    
    static int CCW(long x1, long y1, long x2, long y2, long x3, long y3) {
        long tmp = (x1*y2 + x2*y3 + x3*y1) - (x2*y1 + x3*y2 + x1*y3);
        
        if(tmp > 0)      return 1;  // 반시계
        else if(tmp < 0return -1// 시계
        else             return 0;  // 일직선
    }
    
    // 선분 겹침 여부 판별 함수
    // : 한 선분의 min 값이 다른 선분의 max값보다 클 때 안 겹침
    private static boolean isOverlap(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;
    }
    
    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 isOverlap(x1, y1, x2, y2, x3, y3, x4, y4);   // 겹치는 선분인지 판별
        }
        // 선분이 교차할 때
        else if(abc * abd <= 0 && cda * cdb <= 0) {
            return true;
        }
        return false;
    }
}
cs
✅ 해결 아이디어
✔ CCW를 이용한 선분 교차 여부 판정

 

 


🔺 다른 풀이들

- CCW 설명 굿!! & 변수 x,y를 Point 클래스에 저장해두고 쓰심.

 

[JAVA] CCW

CCW 란? Counter-ClockWise의 줄임말로 평면상의 3개의 점의 위치관계를 판한다는 알고리즘 세 점 A(X1, Y1), B(X2, Y2), C(X3, Y3) 이 있다고 가정했을 때 CCW의 공식은 CCW = ( X1*Y2 + X2*Y3 + X3*Y1 ) - ( X2*Y1 + X3*Y2 + X1*

chb2005.tistory.com

 

 

- 그림 설명

 

[백준(Baekjoon)][자바(java)] 17387 : 선분 교차 2 / 기하

https://www.acmicpc.net/problem/17387 17387번: 선분 교차 2 첫째 줄에 L1의 양 끝 점 x1, y1, x2, y2가, 둘째 줄에 L2의 양 끝 점 x3, y3, x4, y4가 주어진다. www.acmicpc.net import java.io.BufferedReader; import java.io.IOException; im

hyunjiishailey.tistory.com


💬 느낀 점

이렇게 또 응용이 되는구나.... 신기

 

 

 

1회독 2회독 3회독 4회독 5회독
V 7/11      

(참고)

 

CCW를 이용한 선분 교차 여부 판정 (2023-05-12 업데이트)

업데이트 : 2023-05-12 - 코드 잘못된 부분 수정 ( min(p1,p2) ≤ max(q1,q2) && min(q1,q2) ≤ max(p1,p2) 라고 설명은 잘 적어뒀으나, 올린 코드가 잘못됬었음.) line1.p1.compareTo(line2.p2)

nahwasa.com

 

반응형