import sys
 
# 시작점 혹은 도착점이 원 안에 들어있는지 확인
def in_circle(x,y,r,temp_x,temp_y):
    if r**2 > (( x - temp_x)**2) + ((y - temp_y)**2):
        return True
    else: return False
 
# 테스트 케이스
T = int(sys.stdin.readline())
 
result_print = []
#테스트 케이스 동안
for i in range(T):
    #시작점, 도착점
    start_x, start_y, end_x, end_y = map(int, sys.stdin.readline().split())
    # 행성 개수 받기
    planet = int(sys.stdin.readline())
    # 행성 개수만큼 행성 좌표 받기
    result = 0
    for j in range(planet):
        planet_x, planet_y, r = map(int,sys.stdin.readline().split())
        # 출발점과 도착점이 원 안에 있을 경우만 생각
        if in_circle(planet_x,planet_y,r,start_x,start_y) and in_circle(planet_x,planet_y,r,end_x,end_y):
            pass
        elif in_circle(planet_x,planet_y,r,start_x,start_y):
            result += 1
        elif in_circle(planet_x,planet_y,r,end_x,end_y):
            result += 1
    result_print.append(result)
 
for k in result_print:
    print(k) 

적혀있는 문제와 좌표와 원이 난무하는 그림을 보면 정말 풀기 싫어지는 문제 하지만 어떻게 풀지 초반에 생각만 잘 하면 쉽다

처음에는 테스트 케이스를 받고 해당 테스트 케이스 수만큼 행성의 좌표를 받아서 저장 받는건 쉽게 할 수 있고 문제는 어떻게 행성으로 진입/이탈하는 것을 아느냐이다.

보면 어떤 행성이 어디에 있건 간에 어린왕자가 출발하고 도착점에 도달하면서 진입/이탈하는 경우는 출발점이나 도착점이 원 안에 있을 경우밖에 없다. 다른 행성들은 어린왕자가 알아서 무빙치면서 피해갈 것이기 때문에 해당 경우만 생각하면 된다. 이미 원 안에 있으면 무조건 진입/이탈이 필요하니까.

하지만 이 경우에도 생각해야 할 것이 출발점과 도착점이 모두 같은 원 안에 있을 경우를 생각해야 한다. 출발점과 도착점이 같은 원 안에 있다면 굳이 진입/이탈할 필요가 없이 행성 안에서 이동할 수 있기 때문이다.

그러면 우리가 생각할 수 있는 로직은

  • 출발점과 도착점이 같은 원 안에 있을 경우는 패스
  • 출발점만 원 안에 있을 경우에 진입/이탈 횟수 1회 추가
  • 도착점만 원 안에 있을 경우에 진입/이탈 횟수 1회 추가 이다. 이 경우만 생각해주면 나머지는 어린왕자가 알아서 할 것이다.

원 안에 있는지 확인하는 방법은 쉽다. 피타고라스의 방정식을 이용하면 된다. x^2 + y^2 = r^2 이므로 해당 반지름의 제곱보다 출발점/도착점의 좌표가 작으면 안에 있다고 생각할 수 있다.

def in_circle(x,y,r,temp_x,temp_y):
    if r**2 > (( x - temp_x)**2) + ((y - temp_y)**2):
        return True
    else: return False

해당 함수는 행성의 x,y좌표와 반지름, 출발점/도착점을 받아 만약 행성 안에 있으면 True를 반환한다. 이럴 경우에만 result에 1을 추가해주면 된다.

하지만 메모리는 오지게 갉아먹는 모오습