BOJ 6487. 두 직선의 교차 여부
🙇♀️[Silver I] 두 직선의 교차 여부 - 6487
성능 요약
메모리: 2020 KB, 시간: 0 ms
분류
기하학, 수학
제출 일자
2024년 6월 11일 14:33:03
문제 설명
두 개의 직선을 나타내는 4개의 점이 입력으로 주어질 때, 두 직선이 만나는지를 확인하는 프로그램을 작성하시오.
입력
입력의 첫 번째 줄에는 테스트 케이스의 개수 N이 주어진다. (N <= 10)
다음 N개의 줄에는 각각 8개의 정수 x1, y1, x2, y2, x3, y3, x4, y4가 주어진다. 이는 두 직선 (x1, y1)-(x2, y2)와 (x3, y3)-(x4, y4)를 나타낸다.
(x1, y1)과 (x2, y2)는 서로 다른 점이며, (x3, y3)와 (x4, y4)는 서로 다른 점임이 보장된다.
모든 x와 y는 [-1000, 1000] 범위 내의 정수이다.
출력
각각의 테스트 케이스에 대해, 다음과 같이 출력한다.
- 두 직선이 정확히 한 점에서 만난다면, POINT x y의 꼴로 출력한다. 이는 두 직선이 (x,y)에서 교차함을 의미한다. x와 y는 정확히 소숫점 아래 둘째 자리까지 출력한다.
- 두 직선이 만나지 않는다면, NONE을 출력한다.
- 두 직선이 무한히 많은 점에서 만난다면, LINE을 출력한다.
원문에 있는 INTERSECTING LINES OUTPUT/END OF OUTPUT 등은 출력하지 않는다.
🚀풀이
먼저 두 직선의 방정식을 구하고, 교점을 계산한다.
교차되는지 판별식을 통해 알아본다.
그 후, 평행 및 일치 여부를 확인한다.
소수점 둘째 자리까지 출력한다.
두 직선인데 두 선분으로 착각하고 선분 내에 존재하는지 체크하는 함수를 추가해서 문제를 풀었다.
그래서 한번 틀렸다.
또 소수점 둘째 자리까지 출력하는 경우, -0.00으로 출력되는 경우가 있어서 0.00으로 출력되게 만들었다.
🚀코드
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include<iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <math.h>
#include <climits>
#include <cmath>
#include <iomanip>
using namespace std;
// 두 직선의 방정식의 계수를 계산하는 함수
void getLineEquation(double x1, double y1, double x2, double y2, double& A, double& B, double& C)
{
A = y2 - y1;
B = x1 - x2;
C = A * x1 + B * y1;
}
// 두 선분이 교차하는지 확인하는 함수
bool onSegment(double x1, double y1, double x2, double y2, double x, double y)
{
return min(x1, x2) <= x && x <= max(x1, x2) && min(y1, y2) <= y && y <= max(y1, y2);
}
// 정밀한 출력을 위해 0.00과 -0.00을 구별하는 함수
double correctZero(double val)
{
return val == -0.00 ? 0.00 : val;
}
void solve()
{
int N;
cin >> N;
cout << fixed << setprecision(2);
while (N--)
{
double x1, y1, x2, y2, x3, y3, x4, y4;
cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3 >> x4 >> y4;
double A1, B1, C1;
getLineEquation(x1, y1, x2, y2, A1, B1, C1);
double A2, B2, C2;
getLineEquation(x3, y3, x4, y4, A2, B2, C2);
double det = A1 * B2 - A2 * B1;
if (det == 0)
{
// 두 직선이 평행하거나 일치함을 확인
if (A1 * x3 + B1 * y3 == C1)
{
// 일치하는 경우
cout << "LINE" << endl;
}
else
{
// 평행한 경우
cout << "NONE" << endl;
}
}
else
{
// 두 직선이 교차하는 경우
double x = (B2 * C1 - B1 * C2) / det;
double y = (A1 * C2 - A2 * C1) / det;
x = correctZero(x);
y = correctZero(y);
cout << "POINT " << x << " " << y << endl;
//if (onSegment(x1, y1, x2, y2, x, y) && onSegment(x3, y3, x4, y4, x, y))
//{
// cout << "POINT " << x << " " << y << endl;
//}
//else
//{
// cout << "NONE" << endl;
//}
}
}
}
int main()
{
FILE* stream;
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
freopen_s(&stream, "input.txt", "rt", stdin);
solve();
return 0;
}