BOJ 28595 Find the Box

BOJ 28595 Find the Box

문제 링크:

문제 내용

HHWW열의 사각 격자 어딘가에 상자가 하나 놓여 있습니다. 당신은 로봇을 움직여서 상자의 위치를 알아내야 합니다.

당신은 길이 20  00020\;000 이하의 <^>v로 이루어진 쿼리를 던질 수 있습니다. 그러면 로봇은 다음과 같이 움직인 뒤 최종 위치를 당신에게 알려 줍니다.

  • 매 쿼리마다, 로봇은 (0,0)(0, 0)에서 시작합니다. (r,c)(r, c)rr번째 행, cc번째 열에 해당하는 칸을 의미합니다.
  • 각각의 글자에 대해, <이면 왼쪽, ^이면 위쪽, >이면 오른쪽, v이면 아래쪽으로 한 칸 움직입니다. 이때 사각 격자의 밖으로 이동하려고 하거나 상자가 있는 칸으로 이동하려고 하게 되면 로봇은 그 글자를 무시하고 움직이지 않습니다.

인터랙션

먼저 인터랙터가 당신의 프로그램에게 HHWW의 값을 알려 줍니다. (1H,W501 \le H, W \le 50)

당신의 프로그램은 ? <query_string>의 형식으로 출력하여 인터랙터에게 쿼리를 할 수 있습니다. 쿼리를 한 후에는 반드시 flush를 해야 합니다.

그러면 인터랙터는 그 쿼리에 대해 로봇의 최종 위치 (r,c)(r, c)rrcc의 순서로 알려 줍니다.

상자의 위치를 알아냈다면, 상자의 위치가 (r,c)(r, c)일 때 ! r c의 형식으로 출력하고 프로그램을 종료해야 합니다. 이 출력은 쿼리 횟수에 포함되지 않습니다.

모든 테스트 케이스에서 올바른 상자의 위치를 찾았다면, 그 중에서 가장 많은 쿼리 횟수가 qq일 때 min(1002q,100)\min(\frac{100 \sqrt{2}}{\sqrt{q}}, 100)의 점수를 받습니다. q=2q = 2여야 만점을 받을 수 있습니다.

문제 풀이

스포일러

상자가 (r,c)(r, c)에 있다고 합시다. r,c1r, c \ge 1일 경우, 다음과 같은 방법으로 상자의 행 번호를 특정할 수 있습니다.

  • v>>>>>...>>>^>v<<<<<...<<< (>>><<<는 각각 cc번 반복)을 rr번 반복합니다.

이렇게 하면 오른쪽으로 가다가 상자에 막혔을 경우, 상자의 위쪽으로 돌아서 원래 자리로 돌아오게 됩니다. 막히지 않았다면 아래로 한 칸 전진하게 됩니다. 따라서 이때 최종 위치는 (r1,0)(r-1, 0)입니다.

r=0r = 0이거나 c=0c = 0이라면 다음의 결과를 얻습니다.

  • r=0r = 0 또는 (r,c)=(1,0)(r, c) = (1, 0): (H1,0)(H-1, 0)에서 종료
  • 그 외의 경우: (r1,0)(r-1, 0)에서 종료

따라서 이 쿼리를 던지고 그 다음에 같은 쿼리의 대각선 대칭 버전을 던지면, 문제를 거의 풀 수 있습니다. 단순히 이렇게 하면 (0,1)(0, 1)(1,0)(1, 0)이 구분되지 않으므로, 첫 번째 쿼리의 결과가 (H1,0)(H-1, 0)인 경우에 한해 >>>>>>>...>를 던져서 cc를 구하는 방법이 있습니다.

마지막으로 다음과 같은 엣지 케이스를 처리하면 문제를 완전히 풀 수 있습니다.

  • r=1r = 1인 경우: >>>...>를 던지면 마지막으로 멈춘 곳의 바로 오른쪽 칸이 답입니다.
  • c=1c = 1인 경우: vvv...v로 마찬가지로 풀립니다.
  • r=2r = 2인 경우: 이때는 상자가 (1,0)(1, 0)에 있을 경우 쿼리 결과가 (1,1)(1, 1)이 나오게 됩니다. 이것만 따로 처리해 줍니다.
Last updated on