BOJ 28595 Find the Box
문제 내용
행 열의 사각 격자 어딘가에 상자가 하나 놓여 있습니다. 당신은 로봇을 움직여서 상자의 위치를 알아내야 합니다.
당신은 길이 이하의 <^>v로 이루어진 쿼리를 던질 수 있습니다. 그러면 로봇은 다음과 같이 움직인 뒤 최종 위치를 당신에게 알려 줍니다.
- 매 쿼리마다, 로봇은 에서 시작합니다. 는 번째 행, 번째 열에 해당하는 칸을 의미합니다.
- 각각의 글자에 대해,
<이면 왼쪽,^이면 위쪽,>이면 오른쪽,v이면 아래쪽으로 한 칸 움직입니다. 이때 사각 격자의 밖으로 이동하려고 하거나 상자가 있는 칸으로 이동하려고 하게 되면 로봇은 그 글자를 무시하고 움직이지 않습니다.
인터랙션
먼저 인터랙터가 당신의 프로그램에게 와 의 값을 알려 줍니다. ()
당신의 프로그램은 ? <query_string>의 형식으로 출력하여 인터랙터에게 쿼리를 할 수 있습니다. 쿼리를 한 후에는 반드시 flush를 해야 합니다.
그러면 인터랙터는 그 쿼리에 대해 로봇의 최종 위치 를 과 의 순서로 알려 줍니다.
상자의 위치를 알아냈다면, 상자의 위치가 일 때 ! r c의 형식으로 출력하고 프로그램을 종료해야 합니다. 이 출력은 쿼리 횟수에 포함되지 않습니다.
모든 테스트 케이스에서 올바른 상자의 위치를 찾았다면, 그 중에서 가장 많은 쿼리 횟수가 일 때 의 점수를 받습니다. 여야 만점을 받을 수 있습니다.
문제 풀이
스포일러
상자가 에 있다고 합시다. 일 경우, 다음과 같은 방법으로 상자의 행 번호를 특정할 수 있습니다.
v>>>>>...>>>^>v<<<<<...<<<(>>>와<<<는 각각 번 반복)을 번 반복합니다.
이렇게 하면 오른쪽으로 가다가 상자에 막혔을 경우, 상자의 위쪽으로 돌아서 원래 자리로 돌아오게 됩니다. 막히지 않았다면 아래로 한 칸 전진하게 됩니다. 따라서 이때 최종 위치는 입니다.
이거나 이라면 다음의 결과를 얻습니다.
- 또는 : 에서 종료
- 그 외의 경우: 에서 종료
따라서 이 쿼리를 던지고 그 다음에 같은 쿼리의 대각선 대칭 버전을 던지면, 문제를 거의 풀 수 있습니다.
단순히 이렇게 하면 과 이 구분되지 않으므로, 첫 번째 쿼리의 결과가 인 경우에 한해 >>>>>>>...>를 던져서 를 구하는 방법이 있습니다.
마지막으로 다음과 같은 엣지 케이스를 처리하면 문제를 완전히 풀 수 있습니다.
- 인 경우:
>>>...>를 던지면 마지막으로 멈춘 곳의 바로 오른쪽 칸이 답입니다. - 인 경우:
vvv...v로 마찬가지로 풀립니다. - 인 경우: 이때는 상자가 에 있을 경우 쿼리 결과가 이 나오게 됩니다. 이것만 따로 처리해 줍니다.