Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

최's 먹공로그

BOJ1600_말이 되고픈 원숭이 본문

APS

BOJ1600_말이 되고픈 원숭이

ChoiSH313 2019. 8. 23. 21:26

https://www.acmicpc.net/problem/1600


문제정리

1. 말은 체스의 나이트와 같은 이동방식을 가진다.

2. 말은 장애물을 뛰어넘을 수 있다.

3. 원숭이는 총 K번만 말과 같은 움직임을 할 수 있다. 그 외에는 인접한 칸으로만 움직일 수 있다.(상,하,좌,우)

4. map의 맨 왼쪽 위에서 맨 오른쪽 아래까지 가야한다. 격자판이 주어졌을 때, 원숭이가 최소한의 동작으로

도착지점까지 갈 수 있는 방법을 알아내는 프로그램을 작성하시오.

5. map[H][W] 이다. 장애물이 있는 곳으로는 이동할 수 없다.


문제issue

1. 처음에는 최소라서 BFS라고 생각했지만 한 셀에서 원숭이로 갈 수 있는 경우 , 말로 갈 수 있는 경우를 모두

살펴봐야 해서 DFS로 해야겠다고 생각했지만 결론은 최소 = BFS 이다.

2. BFS를 사용하여 한 셀에서 원숭이로 최대 4방향 , 말로 최대 8방향을 가는 경우를 모두 살펴볼 것인가??

- 객체 큐에 위치 , 몇번 움직였는지 cnt , 말의 움직임 기회 k를 가지고 다녀야 한다.

또한, visited를 체크할 때 3차원을 이용해서 말의 움직임을 사용했는지 까지 체크를 해준다.

visited를 3차원을 사용하면 특정 셀에서 원숭이로 올 수 있는 경우와 말을 한 번 사용하고 원숭이로 오는 경우가

다른 움직임으로 처리해서 정확한 visited체크를 할 수 있다.


해결흐름

1. visited[K+1][H][W]로 map[H][W]로 선언해준다.

2. 처음 위치에서 큐에 add해주고 visited의 3차원 모든 값에 true 처리 해준다.

3. 큐에 있는 값에서 말의 기회가 있다면 말의 움직임으로 살펴본다.

(1) 말의 dh = {-2,-2,-1,1,2,2,1,-1} , dw = {-1,1,2,2,1,-1,-1,-1} 이다.

(2) 범위 안이고 장애물이 아니고 visited[k-1][nh][nw] = false이면 말의 움직임으로 갈 수 있는 셀이므로 이동한 뒤

움직임을 나타내는 cnt++ , 말의 움직임 기회를 나타내는 horse-- 해준 뒤 큐에 넣어주고 visited 체크 해준다.

(3) nh == H - 1 이고 nw = W - 1이면 도착지점에 도착했으니 min_cnt 값을 갱신해주고 끝내준다.

4. 말의 움직임이 있든 없든 모든 셀에서 원숭이의 움직임은 다 살펴야 하기 때문에 원숭이의 움직임 조건에는 말의

움직임 기회가 영향을 주지 않는다.

(1) 말의 움직임과 비슷하다. 말의 기회인 horse만 변화를 주지말고 큐에 넣어준다.

5. while(!q.isEmpty)를 돌다가 도착지점에 못가는 경우라면 갈 수 없는 경우이므로 -1을 출력하고 끝낸다.


소스코드