정답률이 그리 낮지 않은 문제인데 푸는데 정말 오래걸렸다.
다른 프로젝트를 하고 있어서도 그랬지만 문제를 풀어가서 답을 구하는데 오랜시간이 걸렸다.
1. 우선 처음에 2차원 배열로 해야되나? 생각했는데 40000 * 40000이라서 이건 아닌거 같애서 이 방법은 넘겼다.
2. 개미의 진행방향과 시간을 인자로 가지는 재귀함수를 호출해서 구하면 어떨까?
=> 구현했더니 예제에 대한 답이 나왔다! 오호
3. But 시간 초과가 났습니다. ㅠㅠ 재귀함수 호출을 무지막지하게 해야 되는 방법이라는 것을 깨달았습니다.
4. 개미가 한 바퀴를 돌고 또 도는 동작이 있다는 걸 발견했습니다. 이렇게 되면 200000000이런식의 수행횟수를 돌아야 하더라도
재귀 호출 횟수를 엄청 줄여 줄 수 있다고 생각했습니다.
그래서 재귀함수 호출을 하는 소스를 사용하면서 위의 사이클을 발견해서 그 부분의 계산량을 줄여주었습니다.
그런데도 시간초과 ㅜㅜ
시간 초과를 극복 할 수 있는 방법으로 문제를 풀어야 했지만 그에 마땅한 방법이 떠오르지 않아 고생하였다.
그래서 백준 질문 게시판을 이용해서 약간의 해답을 얻고 답을 풀었다.
5. 나는 이 문제를 일종의 배열을 한칸한칸 재귀적으로 나가는 방법을 사용했는데, 그 것이 함정이었다.
x, y 좌표가 이동하는 할 때 벽을 부딪히는 것을 한 번의 재귀수행으로 풀어나가야 했던 것이다.
간단히 말해 벽해 부딪힐 때까지 한 번에 진행하는 방식으로 문제를 풀어나갔더니 답이 나왔다.
이렇게 벽을 부딪히는 것을 기준으로 재귀를 수행하게 되면 기존의 방법에 비해 훨씬 더 저렴히, 시간을 쓰면서 답을 해결해나갈 수 있게 된다. 이러한 방법을 생각해내지 못 했던 것이 안타까울 뿐..
물론 소스코드는 간단 명료 하진 않은데 이 부분은 답을 맞췄으니 다른 사람들의 코드를 참고하며 좀 더 보완해야 될 점이다.
재귀 함수를 수행하는 부분을 간단히 설명하자면,
void ant_movement(int x, int y, bool garostate, bool serostate, int movehour);
이런 구조를 갖는 재귀 함수를 설계했다.
garostate와 serostate에 대해서 설명하자면
garostate는 x좌표가 오른쪽으로 이동 상태인지, 왼쪽으로 이동 상태인지를 나타낸다.
serostate는 y좌표가 위쪽으로 이동 상태인지, 아래쪽으로 이동 상태인지를 나태낸다.
현재 좌표점에서 이동 방향중에 위 아래면을 먼저 부딪히게 되면, y좌표의 상태를 바꾸어주고
현재 좌표점에서 이동 방향중에 왼,오른쪽면을 먼저 부딪히게 되면, x좌표의 상태를 바꾸어준다.
이렇게 되면 재귀를 수행하게 되면서 문제에 제시된 특성을 가지면서 이동 할 수 있게 된다.
이러한 코드를 작성하면서 간단명료하게 코드를 작성해주진 못 했지만 로직적으로는 문제 없는 코드를 만들어내었다.
한 가지 더 고려해야 될 점은
재귀를 수행하면서 다음 벽에 부딪히게 되기 전에 최종 시간이 되버리는 케이스가 있게 되는데
예를 들어 재귀함수에서 수행하는 부분은 다음 벽까지 이동하는 것인데 다음 벽까지 이동하기 전에 답이 구해져야 된다. 마지막에 꼭 거치는 부분이다. 이 때는 (최종 목표 시간 - 현재까지의 이동 시간)으로 목표점의 좌표를 구할 수 있게 된다. 마지막 재귀를 마무리 하게 되는 basecase가 되는 것이다.
설명이 길었지만 이런식으로 문제를 풀어나가게 되면 답을 구할 수 있게 된다.
풀고 나니까 쉬웠지만 쉽게 풀지 못 한 문제였다.