Notice
Recent Posts
Recent Comments
Link
«   2026/06   »
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
Archives
Today
Total
관리 메뉴

dh-winternagi 님의 블로그

(17387) 선분 교차 2 본문

백준 (C++)/Solve

(17387) 선분 교차 2

dh-winternagi 2026. 4. 22. 01:19

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

단계별로 풀어보기

39단계(기하 2) 5번째

 

 

 

세 점이 한 직선 위에 있다고 해도 조금만 수정하면 이 교차 판정 알고리즘은 제대로 작동한다.

한 선분과 다른 선분의 양 끝을 ccw로 검사했을 때 0이 있다면 다른 선분은 이 선분을 늘린 직선과 닿는다.

따라서 부호가 반대일 때 말고 0일때도 두 선분은 만난다.

문제는 네 점이 모두 한 직선 위에 있을 때이다. 이때는 각 좌표를 pair처럼 대소를 비교하여 어떤 선분의 양 끝점 사이에 다른 선분의 끝점 중 하나가 있어야 두 선분이 점 또는 선분으로 겹친다는 것이다.

 

 

 

#include <iostream>
using namespace std;

struct Cord{
  long x;
  long y;
  
  Cord(): x(0), y(0) {}
  Cord(long x0, long y0): x(x0), y(y0) {}
  
  bool operator <(const Cord& other) const{
    return make_pair(x,y)<make_pair(other.x,other.y);
  }
  bool operator <=(const Cord& other) const{
    return make_pair(x,y)<=make_pair(other.x,other.y);
  }
};

int main() {
  Cord p[4];
  
  for(int i=0;i<4;i++)  cin >> p[i].x >> p[i].y;
  
  auto ccw= [](Cord &p1, Cord &p2, Cord &p3){
    long t= (p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y);
    
    if(t>0)  return 1;
    else if(t<0)  return -1;
    else  return 0;
  };
  
  auto iscross= [&ccw](Cord &p1, Cord &p2, Cord &p3, Cord &p4){
    long a= ccw(p1,p2,p3)*ccw(p1,p2,p4);
    long b= ccw(p4,p3,p1)*ccw(p4,p3,p2);
    
    if(a==0 && b==0){
      return (min(p1,p2)<=max(p3,p4) && min(p3,p4)<=max(p1,p2));
    }else if(a<=0&&b<=0){
      return true;
    }else{
      return false;
    }
  };
  
  cout << iscross(p[0], p[1], p[2], p[3]);
  
  return 0;
}

'백준 (C++) > Solve' 카테고리의 다른 글

(2162) 선분 그룹  (0) 2026.04.22
(20149) 선분 교차 3  (0) 2026.04.22
(17386) 선분 교차 1  (0) 2026.04.22
(25308) 방사형 그래프  (0) 2026.04.22
(11758) CCW  (0) 2026.04.21