[백준/파이썬] 1004번 어린 왕자 풀이

업데이트:



문제 정보


풀이

문제

백준 어린왕자

간단히 말해서, 출발점부터 도착점까지 가는데 원과 최소한의 횟수만큼 교차할 때, 그 횟수를 출력하라는 문제입니다.

코드

import sys;read=sys.stdin.readline
for T in range(int(read())):
    x1,y1,x2,y2=map(int,read().split())
    n=int(read())
    l=[list(map(int,read().split()))for i in range(n)]
    t=0
    for c in l:
        if (x1-c[0])**2+(y1-c[1])**2 < c[2]**2:
            if (x2-c[0])**2+(y2-c[1])**2 < c[2]**2:pass
            else:t+=1
        elif (x2-c[0])**2+(y2-c[1])**2 < c[2]**2:t+=1
    print(t)

설명

여러 테스트 케이스에 걸쳐 입력을 받는 문제들은 입력에만 상당한 시간을 소모하여 채점이 오래걸리게 되니, input() 함수 대신 sys.stdin.readline() 함수를 이용해 입력을 받도록 했습니다.

원의 좌표정보를 담은 리스트를 l에 배정합니다. 이후, l의 각 원소를 반복합니다.

이때, 각 원소는 [x좌표, y좌표, 반지름]으로 구성된 하나의 원입니다.

즉, for c in l 반복문을 통해 원을 하나씩 어떠한 ‘조건’을 시험해봅니다.

우리가 해당 원을 꼭 거쳐가야 한다면 시작점 또는 도착점이 그 원 안에 있는 것으로 볼 수 있습니다. 그렇지 않다면 그냥 빙~ 둘러가면 될 뿐이니까요

하지만, 시작점과 도착점 모두를 포함하는 아주 큰 원이 있다면 어떨까요?

당연히 원 안에서만 움직이면 될테니 해당 원과는 경로가 교차하지 않습니다.

다시말해, 그 조건은 시작점과 도착점중 하나만이 해당 원 안에 있는가? 입니다.

이 조건을 주어진 모든 원에 대해 테스트해보며 참인 경우에만 카운트를 1해줍니다.

xor 논리 연산자를 지원하는 언어라면 간단하게 xor연산으로도 풀 수 있습니다.

파이썬의 경우도 사실 아래와 같이 논리값 대신 비트를 배정하여 xor연산을 할 수 있겠죠?

import sys;read=sys.stdin.readline
for T in range(int(read())):
    x1,y1,x2,y2=map(int,read().split())
    n=int(read())
    l=[list(map(int,read().split()))for i in range(n)]
    t=0
    for c in l:
        A = 1 if (x1-c[0])**2+(y1-c[1])**2 < c[2]**2 else 0
        B = 1 if (x2-c[0])**2+(y2-c[1])**2 < c[2]**2 else 0
        if  A^B==1:t+=1
    print(t)


댓글남기기