n행 m열의 격자가 있습니다. 격자의 각 행은 0, 1, ..., n-1번의 번호, 그리고 각 열은 0, 1, ..., m-1번의 번호가 순서대로 매겨져 있습니다. 당신은 이 격자에 공을 하나 두고, 그 공에 다음과 같은 쿼리들을 날리고자 합니다.
열 번호가 감소하는 방향으로 dx칸 이동하는 쿼리 (query(0, dx))
열 번호가 증가하는 방향으로 dx칸 이동하는 쿼리 (query(1, dx))
행 번호가 감소하는 방향으로 dx칸 이동하는 쿼리 (query(2, dx))
행 번호가 증가하는 방향으로 dx칸 이동하는 쿼리 (query(3, dx))
단, 공은 격자 바깥으로 이동할 수 없으며, 목적지가 격자 바깥인 경우 공은 이동하다가 더 이상 이동할 수 없을 때 멈추게 됩니다. 예를 들어, 5행 × 4열 크기의 격자 내의 공이 3행 2열에 있을 때 query(3, 10) 쿼리를 받은 경우 공은 4행 2열에서 멈추게 됩니다. (격자의 크기가 5행 × 4열이므로, 0~4번 행과 0~3번 열로 격자가 구성되기 때문입니다.)
격자의 행의 개수 n, 열의 개수 m, 정수 x와 y, 그리고 쿼리들의 목록을 나타내는 2차원 정수 배열 queries가 매개변수로 주어집니다. n × m개의 가능한 시작점에 대해서 해당 시작점에 공을 두고 queries 내의 쿼리들을 순서대로 시뮬레이션했을 때, x행 y열에 도착하는 시작점의 개수를 return 하도록 solution 함수를 완성해주세요.
n m x y queries result
2 2 0 0 [[2,1],[0,1],[1,1],[0,1],[2,1]] 4
2 5 0 1 [[3,1],[2,2],[1,1],[2,3],[0,1],[2,1]] 2
처음에는 부르트포스로 접근을 하였다가 당연하게도 시간초과를 만났다. 결국 구글을 찾아보게 되었고 top, bottom, left, right 변수로 범위를 기억하여 이 범위의 넓이를 구하면 가능한 출발점의 수를 모두 구할 수 있다는 사실을 알았다. 물론 범위를 구한 후에 top이 n-1보다 크면 안되고 bottom은 0보다 작아서는 안되며 left는 m-1보다 크면 안되고 right는 0보다 작으면 안된다.
def solution(n, m, x, y, queries):
answer = 0
t, l, r, b = x, y, y, x
queries.reverse()
for i, j in queries:
if i == 0:
if r+j<m:
tmp=r+j
else:
tmp=m-1
if l == 0:
r = tmp
else:
l, r = l + j, tmp
if i == 1:
if l-j>=0:
tmp=l-j
else:
tmp=0
if r == m - 1:
l = tmp
else:
l, r = tmp, r - j
if i == 2:
if b+j<n:
tmp=b+j
else:
tmp=n-1
if t == 0:
b = tmp
else:
t, b = t + j, tmp
if i == 3:
if t-j>=0:
tmp=t-j
else:
tmp=0
if b == n - 1:
t = tmp
else:
t, b = tmp, b - j
if l > m - 1 or r < 0 or t > n - 1 or b < 0:
break
else:
answer = ((b - t) + 1) * ((r - l) + 1)
return answer