백준문제풀이

백준 문제 11758번 CCW 문제풀이 c++

노가다 김씨 2022. 3. 13. 09:43

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

 

11758번: CCW

첫째 줄에 P1의 (x1, y1), 둘째 줄에 P2의 (x2, y2), 셋째 줄에 P3의 (x3, y3)가 주어진다. (-10,000 ≤ x1, y1, x2, y2, x3, y3 ≤ 10,000) 모든 좌표는 정수이다. P1, P2, P3의 좌표는 서로 다르다.

www.acmicpc.net

 

문제해석

 

이 문제를 풀기 전에는 CCW란 알고리즘을 몰라서 그냥 수학 느낌으로 접근해서 풀었다.

 

p1 p2가 이루는 선분을 A p1 p3가 이루는 선분을 B라고 하면

A의 기울기가 B의 기울기보다 클 경우 p1 p2 p3 를 잇는 선분은 시계 방향으로 꺽이니까 -1을 

A의 기울기가 B의 기울기보다 작을 경우 p1 p2 p3 를 잇는 선분은 반시계 방향으로 꺽이니까 1을

A의 기울기가 B의 기울기와 같은경우 p1 p2 p3 를 잇는 선분은 직선을 이루므로 0을 출력한다라고 볼 수있다.

 

A의 기울기는 y1-y2/(x1-x2) B의 기울기는 y1-y3/(x1-x3)이다.

0으로 나누는 예외 (x1=x2 또는 x1=x3인경우) 를 작성해주고 else 부분에 double 형인 y1-y2/(x1-x2) 와 y1-y3/(x1-x3)를 비교했더니 처음엔 틀렸다.

 

틀린 이유는 보나마나 실수오차일거라고 생각을 했고 분모의 최소공배수를 곱해서 (x1-x3)(y1-2)와 (x1-x2)(y1-y2)를 비교했더니 AC를 받았다.

 

코드

 

#include <iostream>
#include <algorithm>
typedef long long int ll;
using namespace std;
ll ccw(ll x1,ll x2,ll x3,ll y1,ll y2,ll y3);
int main(){
    cout.tie(NULL);
    cin.tie(NULL);
    ios_base::sync_with_stdio(false);
    ll x[3];
    ll y[3];
    for(ll i=0; i<3; i++)
    {
        cin>>x[i]>>y[i];
    }
	cout<<ccw(x[0],x[1],x[2],y[0],y[1],y[2]);
}
ll ccw(ll x1,ll x2,ll x3,ll y1,ll y2,ll y3){
    if(x1==x2)
    {
        if(x3>x1)
        {
            return -1;
        }
        else if(x3<x1)
        {
            return 1;
        }
    }
    else if(x1==x3)
    {
        if(y3<y1)
        {
            return -1;
        }
        else if(y3>y1)
        {
            return 1;
        }
    }
    else
    {
        ll a=(x1-x3)*(y1-y2);
        ll b=(x1-x2)*(y1-y3);
        if(a<b)
        {
            return 1;
        }
        else if(a>b)
        {
            return -1;
        }
    }
    return 0;
}