본문 바로가기

💻 Computer Science/Algorithm🐇

[python] 백준 1002 : 터렛

728x90
반응형

좌표평면상 어느 한 점에서 일정한거리 r만큼 떨어진 점들의 집합은? 원이죠. 반지름이 r인 원입니다.

입력받은 두개의 좌표를 중심으로하는 각 반지름 r1,r2인 두 원의 교점의 갯수를 구하는문제로 볼수있습니다. 대놓고 수학문제네요. 

어렵지않은 문제지만 그림을 그려봤으니 시각자료로 써보겠읍니다(나름 신경써서 그렸습니다..) 

각 두점에서 만나는, 접하는 (한점에서 만나는), 만나지않는 케이스입니다. 여기서 누락된 케이스는 두 원이 일치할때, 즉 중심과 반지름이 같을때 무한대의 교점을갖는 케이스입니다. 

 

내/외 관점으로보면, 두점 사이 거리가 큰원의 반지름보다 클때 두 원은 서로의 외부에있습니다. 외부에 있다는 말의 의미는 작은원의 중심이 큰원 외부에 있다는겁니다. 이때는 두점사이 거리와 반지름합의 대소비교로 교점갯수를 구할수있습니다. 외부에있을땐 두점사이 거리가 반지름합보다 크다면 두 원은 만나지않습니다. 교점이 0이겠죠.

두점사이거리가 반지름합과 같다면 두원은 외접하고, 반지름합이 크다면 두점에서 만납니다.

내부 케이스는 또 다릅니다. 두점 사이거리보다 큰원의 반지름이 클때 작은원의 중심은 큰원 내부안에 있는 이른바 '내부 케이스'인데요. 이때는 교점을 메기는 기준이 좀 달라집니다. 이땐 두점 사이거리와 작은원 반지름의 합을 큰원 반지름과 대소비교하여 교점갯수를 세주면 됩니다.

 

이렇게 주저리 주저리설명한 내용을 최대한 간결하게 코드로 나타내봅시다. 이 문제는 if조건을 간결하게 쓰는게 중요할것같네요

T=int(input())
for _ in range(T):
    x1,y1,r1,x2,y2,r2=map(int,input().split())

    d=((x1-x2)**2+(y1-y2)**2)**(1/2)

    sum_r=r1+r2
    max_r=max(r1,r2)
    min_r=min(r1,r2)

    if d>max_r:
        if d>sum_r:
            cnt=0
        elif d==sum_r:
            cnt=1
        else:
            cnt=2

    elif d<max_r:
        if d==0:
            if r1==r2:
                cnt=-1
            else:
                cnt=0
        elif d+min_r<max_r:
            cnt=0

        elif d+min_r==max_r:
            cnt=1

        elif d+min_r>max_r:
            cnt=2

    else:
        cnt=2

    print(cnt)

 

흠,, 이렇게도 답이 나오긴하는데요 쓸데없이 너무길죠? 

 

관점을 바꿔봅시다. 내/외 관점이 아니라 어떨때 교점이(출력값이) -1,0,1,2가 각각 나오는지를 정리해서 if문에 넣어주는게 훨씬 간결하겠네요

 

T=int(input())
for _ in range(T):
    x1,y1,r1,x2,y2,r2=map(int,input().split())

    d=((x1-x2)**2+(y1-y2)**2)**(1/2)

    sum_r=r1+r2
    max_r=max(r1,r2)
    min_r=min(r1,r2)

    if d==0 and r1==r2:
        cnt=-1
    elif d>r1+r2 or d+min_r<max_r:
        cnt=0
    elif abs(r1-r2)==d or r1+r2==d:
        cnt=1
    else:
        cnt=2
        
    print(cnt)

 

위에서 내부/외부 얘기하면서 각 케이스를 구분한 내용을 관점만 바꿔서 다시 작성한 코드입니다. 훨씬 간결해졌죠?

복잡하게 내/외 생각할것도 없이 그냥 "어떨때 -1을 출력해야하고.. 어떨때 0,1,2를 출력해야할까?" 로 접근하는게 효율적이네요. 아마 수학내용중에 아는게나와 막 흥분했던것 같읍니다. 분명 중등수학땐 내부/외부로 배웠지만 컴퓨터 입장에선 효율성이 떨어지는 방법이네요. 

반응형