4115:鸣人和佐助,考点:广搜去重
原题:http://bailian.openjudge.cn/practice/4115/
描述
已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置。地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要先打败大蛇丸的手下才能到这些位置。鸣人有一定数量的查克拉,每一个单位的查克拉可以打败一个大蛇丸的手下。假设鸣人可以往上下左右四个方向移动,每移动一个距离需要花费1个单位时间,打败大蛇丸的手下不需要时间。如果鸣人查克拉消耗完了,则只可以走到没有大蛇丸手下的位置,不可以再移动到有大蛇丸手下的位置。佐助在此期间不移动,大蛇丸的手下也不移动。请问,鸣人要追上佐助最少需要花费多少时间?
输入
输入的第一行包含三个整数:M,N,T。代表M行N列的地图和鸣人初始的查克拉数量T。0 < M,N < 200,0 ≤ T < 10
后面是M行N列的地图,其中@代表鸣人,+代表佐助。*代表通路,#代表大蛇丸的手下。
输出
输出包含一个整数R,代表鸣人追上佐助最少需要花费的时间。如果鸣人无法追上佐助,则输出-1。
样例输入
样例输入1 4 4 1 #@## **## ###+ **** 样例输入2 4 4 2 #@## **## ###+ ****
样例输出
样例输出1 6 样例输出2 4
解法
思路:广搜,每个点的状态包括坐标轴、时间、此时的查克拉数量。
这道题的关键在于去重,拥有不同查克拉数量走到同一个点状态视为不同的,因为接下来可以走的路是不同的。而且查克拉数目也不多,最多才10个,直接作为一维加入数组中也不会炸。
代码如下:
1 #include <iostream> 2 #include <queue> 3 #include <cstring> 4 #define INF 1<<30 5 using namespace std; 6 struct point { 7 int x, y; 8 int min; 9 int cha; 10 point(int inx,int iny,int m,int k):x(inx),y(iny),min(m),cha(k){} 11 }; 12 bool visited[205][205][11]; 13 char G[205][205]; 14 int dx[4] = { -1,1,0,0 }; 15 int dy[4] = { 0,0,-1,1 }; 16 int main() { 17 memset(G, 0, sizeof(G)); 18 memset(visited, 0, sizeof(visited)); 19 int M, N, T; 20 cin >> M >> N >> T; 21 queue<point>myqueue; 22 int result = INF; 23 for(int i=0;i<M;i++) 24 for (int j = 0; j < N; j++) { 25 cin >> G[i][j]; 26 if (G[i][j] == '@') { 27 myqueue.push(point(i, j, 0, T)); 28 visited[i][j][T] = 1; 29 } 30 } 31 while (!myqueue.empty()) { 32 point top = myqueue.front(); 33 myqueue.pop(); 34 if (G[top.x][top.y] == '+') { 35 if (result > top.min) 36 result = top.min; 37 continue; 38 } 39 if (top.min + 1 >= result) 40 continue; 41 for (int i = 0; i < 4; i++) { 42 int tx = top.x + dx[i]; 43 int ty = top.y + dy[i]; 44 if (tx < 0 || tx >= M || ty < 0 || ty >= N) 45 continue; 46 if (G[tx][ty] == '#') { 47 if (top.cha - 1 >= 0) { 48 if (visited[tx][ty][top.cha - 1]) 49 continue; 50 visited[tx][ty][top.cha-1] = 1; 51 myqueue.push(point(tx, ty, top.min + 1, top.cha - 1)); 52 } 53 } 54 else { 55 if (visited[tx][ty][top.cha]) 56 continue; 57 visited[tx][ty][top.cha] = 1; 58 myqueue.push(point(tx, ty, top.min + 1, top.cha)); 59 } 60 } 61 } 62 if (result == INF) 63 cout << -1 << endl; 64 else 65 cout << result << endl; 66 return 0; 67 }