[C++]선분 교차 2 - 백준17387
문제
풀이
문제 해석을 하자면,
- 두 직선이 교차하는지 판별하는 문제
풀이
- 조건부분에 “한 선분의 끝 점이 다른 선분이나 끝 점 위에 있는 것도 교차하는 것” 고려해줘야 한다.
- 이 때문에 꼭, 같은 직선상에 존재하는 두 직선의 교차 여부도 예외로 처리할 것(between함수 활용)
- 추가로 long long 타입으로 계산할 것. int형은 범위에 한계가 있음.
- 행렬식 계산 때문에 최대 범위가 1,000,000^4
- long long으로도 범위 문제가 있으면 double 사용
코드
#include<iostream>
using namespace std;
struct point {
long long x; long long y;
};
typedef point Point;
long long ccw2(Point p, Point q) {
return p.x * q.y - p.y * q.x;
}
long long ccw(Point r, Point p, Point q) {
// r만큼 빼서 원점으로 이동 (ccw2 계산 위해)
p.x -= r.x;
p.y -= r.y;
q.x -= r.x;
q.y -= r.y;
return ccw2(p, q);
}
int direction(Point a, Point b, Point c) {
if (ccw(a, b, c) > 0) return 1;
if (ccw(a, b, c) < 0) return -1;
if (ccw(a,b,c) == 0) return 0;
}
// 점 c가 a,b직선 상에 존재하는지 판별함수
bool between(Point a, Point b, Point c) {
// 1. 일직선 상에 존재하나 확인
if (ccw(a, b, c) != 0) return false;
else {
// 2. 수직 여부 확인 후 범위제한
if (a.x == b.x) {
if ((c.y >= a.y && c.y <= b.y) || (c.y >= b.y && c.y <= a.y)) return true;
}
else {
if ((c.x >= a.x && c.x <= b.x) || (c.x >= b.x && c.x <= a.x)) return true;
}
return false;
}
}
int interection(Point a, Point b, Point c, Point d) {
// (a,b,c)*(a,b,d) ==-1 && (c,d,a)*(c,d,b)==-1 성립하면 교차
// 추가조건 때문에 <=0로 판별
if (direction(a, b, c) * direction(a, b, d) <= 0 && direction(c, d, a) * direction(c, d, b) <= 0) {
// direction함수는 방향만을 나타내기 때문에 만약 0인 경우 일직선상인 건데,
// 두 직선이 서로 접하는지 범위제한을 줘서 판단할 필요가 있음(between 함수 활용)
if (direction(a, b, c) * direction(a, b, d) == 0 && direction(c, d, a) * direction(c, d, b) == 0) {
// 점 c또는 d가 a,b직선 상에 존재하나 판단
// 점 a또는 b가 c,d직선 상에 존재하나 판단
if (between(a, b, c) || between(a, b, d)|| between(c, d, a) || between(c, d, b)) {
return 1;
}
else
return 0;
}
return 1;
}
else
return 0;
}
Point inPoint[4];
int main() {
// input
for (int i = 0; i < 4; i++) {
cin >> inPoint[i].x >> inPoint[i].y;
}
// run && output
cout << interection(inPoint[0], inPoint[1], inPoint[2], inPoint[3]);
return 0;
}
느낀점
생략
댓글남기기