[BaekJoon] 17387 선분 교차 2 (Java)

오태호·2023년 3월 5일
0

백준 알고리즘

목록 보기
166/395
post-thumbnail

1.  문제 링크

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

2.  문제



요약

  • 2차원 좌표 평면 위의 두 선분 L1,L2L_1, L_2가 주어졌을 때, 두 선분이 교차하는지 아닌지 구하는 문제입니다.
  • 한 선분의 끝 점이 다른 선분이나 끝 점 위에 있는 것도 교차하는 것입니다.
  • L1L_1의 양 끝 점은 (x1,y1x_1, y_1), (x2,y2x_2, y_2), L2L_2의 양 끝 점은 (x3,y3x_3, y_3), (x4,y4x_4, y_4)입니다.
  • 입력: 첫 번째 줄에 -1,000,000보다 크거나 같고 1,000,000보다 작거나 같은 정수인 L1L_1의 양 끝 점 x1,y1,x2,y2x_1, y_1, x_2, y_2가 주어지고 두 번째 줄에 보다 -1,000,000보다 크거나 같고 1,000,000보다 작거나 같은 정수인 L2L_2의 양 끝 점 x3,y3,x4,y4x_3, y_3, x_4, y_4가 주어집니다.
    • 선분의 길이는 0보다 큽니다.
  • 출력: 첫 번째 줄에 L1L_1L2L_2가 교차하면 1, 아니면 0을 출력합니다.

3.  소스코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    static Point[] points;

    static void input() {
        Reader scanner = new Reader();
        points = new Point[4];

        for(int idx = 0; idx < 4; idx++) {
            long x = scanner.nextLong(), y = scanner.nextLong();
            points[idx] = new Point(x, y);
        }
    }

    static void solution() {
        boolean isEnd = false;
        int result = 0;

        int ccw123 = ccw(points[0], points[1], points[2]);
        int ccw124 = ccw(points[0], points[1], points[3]);
        int ccw341 = ccw(points[2], points[3], points[0]);
        int ccw342 = ccw(points[2], points[3], points[1]);

        if(ccw123 * ccw124 == 0 && ccw341 * ccw342 == 0) {
            isEnd = true;

            boolean c1 = Math.min(points[0].x, points[1].x) <= Math.max(points[2].x, points[3].x);
            boolean c2 = Math.min(points[2].x, points[3].x) <= Math.max(points[0].x, points[1].x);
            boolean c3 = Math.min(points[0].y, points[1].y) <= Math.max(points[2].y, points[3].y);
            boolean c4 = Math.min(points[2].y, points[3].y) <= Math.max(points[0].y, points[1].y);

            if(c1 && c2 && c3 && c4)
                result = 1;
        }
        
        if(!isEnd) {
            if(ccw123 * ccw124 <= 0 && ccw341 * ccw342 <= 0) {
                result = 1;
            }
        }

        System.out.println(result);
    }

    static int ccw(Point p1, Point p2, Point p3) {
        long num1 = p1.x * p2.y + p2.x * p3.y + p3.x * p1.y;
        long num2 = p1.y * p2.x + p2.y * p3.x + p3.y * p1.x;
        
        // 반시계
        if(num1 - num2 > 0) {
            return 1;
        } else if(num1 == num2) { // 평행
            return 0;
        } else { // 시계방향
            return -1;
        }
    }

    static class Point {
        long x, y;

        public Point(long x, long y) {
            this.x = x;
            this.y = y;
        }
    }

    public static void main(String[] args) {
        input();
        solution();
    }

    static class Reader {
        BufferedReader br;
        StringTokenizer st;

        public Reader() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while(st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            return st.nextToken();
        }

        long nextLong() {
            return Long.parseLong(next());
        }
    }
}
profile
자바, 웹 개발을 열심히 공부하고 있습니다!

0개의 댓글