💻 Computer Science/Algorithm🐇

[python] 백준 1064 : 평행사변형

노가다 권씨 2024. 2. 16. 01:17
728x90
반응형

세 점이 입력값으로 주어지므로 평행사변형은 총 3개를 만들수있습니다. 세 점이 결정된이상 나머지 한점은 구할필요가 없고 아래 그림 3가지경우중 한가지로 자동 결정됩니다.

세 점에다가 번호를 붙여봤는데요.. 평행사변형의 경우 "평행하지 않은 두 변의 길이만 결정되면 둘레는 두변길이합 x2" 로 구할수있습니다. 둘레는 두 변이 1번점에서 뻗어나오는경우, 2번,3번점에서 뻗어나오는경우 총 3가지 경우가 있져.

그럼 이 세가지 경우의 최댓값-최솟값으로 답을 구할수있겠네요. 

만약 평행사변형이 만들어지지않는 경우엔 -1을 출력하랍니다. 어떤경우에 평행사변형이 만들어지지 않을까요? 

1. 세 점이 일직선상에 있는경우, 2. 두점이 같을경우, 3. 세점이 모두 같을경우 일단 이정도 생각이나네요 

 

그럼 논리구조를 정리해봅시다.

평행하지않은 두 변의 길이가 결정되면 평행사변형의 둘레를 구할수있습니다. 우리는 두 변의 길이가 나오는 경우를 따져주면 되지요. 주어진 점이 3개이므로 3점에서 나올수있는 두 변의 길이합은 3가지입니다. 이걸로 평행사변형의 둘레를 구할수있죠. 이 경우의 2x최댓값-2x최솟값을 해주면됩니다. 위에서 기술한 3가지의 예외경우는 if문으로 제외해줍시다. 

일직선상에있다 -> 1,2번점을 이은 직선과 2,3번점을 이은 직선의 기울기가 같다. 두점 혹은 세점이같다. -> 좌표가 동일하다. 이대로 코드를 작성하면 되겠네요

 

x1,y1,x2,y2,x3,y3 = map(int,input().split())

dist_1 = ((x1-x2)**2+(y1-y2)**2)**(1/2)+((x1-x3)**2+(y1-y3)**2)**(1/2)
dist_2 = ((x2-x1)**2+(y2-y1)**2)**(1/2)+((x2-x3)**2+(y2-y3)**2)**(1/2)
dist_3 = ((x3-x1)**2+(y3-y1)**2)**(1/2)+((x3-x2)**2+(y3-y2)**2)**(1/2)

min_dist = min(dist_1,dist_2,dist_3)
max_dist = max(dist_1,dist_2,dist_3)

if x1==x2 or x2==x3 or x1==x3:
    if x1==x2==x3 or  (x1==x2 and y1==y2) or (x2==x3 and y2==y3) or (x1==x3 and y1==y3):
        print('-1.0')
    else:
        print(max_dist*2 - min_dist*2)

elif (y1-y2)/(x1-x2)==(y2-y3)/(x2-x3):
    print('-1.0')
    
else:
    min_dist = min(dist_1,dist_2,dist_3)
    max_dist = max(dist_1,dist_2,dist_3)

    print(max_dist*2 - min_dist*2)

위의 논리구조대로 작성한 코드입니다.  첫번째 if문에서 점 일치에 대해 x에대한 조건만 준 이유는 밑에 elif문에서 기울기를 판별할때 x1==x2가 되버리면 0으로 나누는꼴이므로 오류가 발생하게됩니다. 해당 케이스에 대해 방지하는 동시에 점이 일치하는 경우를 동시에 잡아줍니다.

 

이 문제에선 나머지한점을 굳이 구할필요가 없다는점, 왜냐면 우리의 목표는 그냥 둘렛값을 구하는거니까. 둘레는 평행하지않은 두 선분의 길이만 알면 구할수있다는걸 이용해 푸는것이 중요하겠네요.

그러나!

이렇게 끝내기엔 코드에 수정할수있는 부분이 있죠. 기울기를 구할때 x좌표가 같다면 분모가 0이 되어 오류가 발생하는걸 방지하려고, 분모가 0이되는 케이스에 대해 따로 떼놓고 if문을 썼는데요. 사실 elif문의 기울기조건 하나만으로 모든 '평행사변형을 만들수없는 경우'가 다 걸립니다. 모든 케이스를 다 커버할수있는 훌륭한 조건을 두고, 경우를 나눠 따로 떼어놓는건 비효율 + if문에서 경우를 누락할수있는 리스크가 있습니다. 

이땐 식을 조금 정리해주면 저 기울기조건을 x좌표가 같은경우에도 오류없이 사용할수있습니다. (y1-y2)/(x1-x2) == (y2-y3)/(x2-x3)이면 양변에 (x1-x2)(x2-x3)을 곱해서 분모를 없애버리면 되지요.

 

x1,y1,x2,y2,x3,y3 = map(int,input().split())

dist_1 = ((x1-x2)**2+(y1-y2)**2)**(0.5)+((x1-x3)**2+(y1-y3)**2)**(0.5)
dist_2 = ((x2-x1)**2+(y2-y1)**2)**(0.5)+((x2-x3)**2+(y2-y3)**2)**(0.5)
dist_3 = ((x3-x1)**2+(y3-y1)**2)**(0.5)+((x3-x2)**2+(y3-y2)**2)**(0.5)

min_dist = min(dist_1,dist_2,dist_3)
max_dist = max(dist_1,dist_2,dist_3)

if (y1-y2)*(x2-x3)==(y2-y3)*(x1-x2):
    print('-1.0')
    
else:
    min_dist = min(dist_1,dist_2,dist_3)
    max_dist = max(dist_1,dist_2,dist_3)

    print(max_dist*2 - min_dist*2)

코드가 훨씬 간결해지고 무엇보다 안정적입니다. 실수만 하지않는다면 나름 간단히 해결할수있는 문제였네요

반응형