1+ /* *
2+ * @file 1600.cpp
3+ * @brief 말이 되고픈 원숭이
4+ * @author Sam Kim (samkim2626@gmail.com)
5+ *
6+ * BFS
7+ * DFS로 풀면 최소한의 동작을 구할 수 없음
8+ * DP로도 풀 수 있을 것 같다는 생각? -> 시작점에서 도착점이 왼쪽위에서 오른쪽아래로 정해져있기 때문에?
9+ *
10+ * 말의 움직임 k번만. 어떻게 k번을 움직이는게 좋을까?
11+ * 1. 처음 풀이에는 먼저 말처럼 움직이는 것 진행 -> 이 경우 말로 이동하여 도착할 수 있는 경우 안됨
12+ * 2. 그러면 매 스텝에서 말의 움직임의 횟수를 고려하는 경로를 설정해보자 -> visited에 (말 이동한 횟수) 차원 추가
13+ *
14+ * 추가) x, y - w, h 그래프 입력받을 때 주의할 것
15+ */
16+ #include < iostream>
17+ #include < tuple>
18+ #include < queue>
19+
20+ using namespace std ;
21+
22+ int k, w, h;
23+ int g[200 ][200 ];
24+ bool visited[200 ][200 ][31 ];
25+ pair<int , int > horse[8 ] = {{1 , -2 }, {2 , -1 }, {2 , 1 }, {1 , 2 }, {-1 , 2 }, {-2 , 1 }, {-2 , -1 }, {-1 , -2 }};
26+ pair<int , int > monkey[4 ] = {{-1 , 0 }, {0 , -1 }, {1 , 0 }, {0 , 1 }};
27+
28+ int bfs (int startX, int startY)
29+ {
30+ int step = 0 ;
31+ int nHorse = 0 ; // 말처럼 이동한 횟수
32+ queue<tuple<int , int , int , int >> q;
33+ q.push (make_tuple (startX, startY, step, nHorse));
34+ visited[startX][startY][nHorse] = true ;
35+
36+ while (!q.empty ())
37+ {
38+ tuple<int , int , int , int > t = q.front ();
39+ int x = get<0 >(t);
40+ int y = get<1 >(t);
41+ step = get<2 >(t);
42+ nHorse = get<3 >(t);
43+ q.pop ();
44+
45+ if (x == w - 1 && y == h - 1 )
46+ {
47+ return step;
48+ }
49+
50+ int newX, newY;
51+ // 말처럼 이동
52+ if (nHorse < k)
53+ {
54+ for (int i = 0 ; i < 8 ; i++)
55+ {
56+ newX = x + horse[i].first ;
57+ newY = y + horse[i].second ;
58+ if (!visited[newX][newY][nHorse + 1 ] && newX >= 0 && newX < w && newY >= 0 && newY < h && g[newX][newY] != 1 )
59+ {
60+ visited[newX][newY][nHorse + 1 ] = true ;
61+ q.push (make_tuple (newX, newY, step + 1 , nHorse + 1 ));
62+ }
63+ }
64+ }
65+
66+ // 원숭이 이동
67+ for (int i = 0 ; i < 4 ; i++)
68+ {
69+ newX = x + monkey[i].first ;
70+ newY = y + monkey[i].second ;
71+ if (!visited[newX][newY][nHorse] && newX >= 0 && newX < w && newY >= 0 && newY < h && g[newX][newY] != 1 )
72+ {
73+ visited[newX][newY][nHorse] = true ;
74+ q.push (make_tuple (newX, newY, step + 1 , nHorse));
75+ }
76+ }
77+ }
78+
79+ return -1 ;
80+ }
81+
82+ int main ()
83+ {
84+ ios_base::sync_with_stdio (false );
85+ cin.tie (nullptr );
86+
87+ cin >> k >> w >> h;
88+ for (int i = 0 ; i < h; i++)
89+ {
90+ for (int j = 0 ; j < w; j++)
91+ {
92+ cin >> g[j][i];
93+ }
94+ }
95+
96+ cout << bfs (0 , 0 ) << ' \n ' ;
97+
98+ return 0 ;
99+ }
0 commit comments