佐助和鸣人
描述 http://cxsjsxmooc.openjudge.cn/2017t2winterw10/3/
已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置。地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要先打败大蛇丸的手下才能到这些位置。鸣人有一定数量的查克拉,每一个单位的查克拉可以打败一个大蛇丸的手下。假设鸣人可以往上下左右四个方向移动,每移动一个距离需要花费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
#include<iostream> using namespace std; #define Max 10 int R, C, T; // int maze[Max][Max]; //地图; struct Node { int r, c; int n; //能量; int steps; //走了多少步; Node () { } Node(int rr, int cc,int nn, int s) :r(rr), c(cc),n(nn), steps(s) { } }; Node open[Max*Max]; //open表; int head = 0; int tail = 0; //头尾指针; Node start, goal;//鸣人的起始地点; int visited[Max][Max][Max]; //标记走过的状态; int dir[4][2] = { 1,0, -1, 0, 0, 1, 0, -1 }; //方向; int main() { cin >> R >> C >> T; for (int i = 0; i < R; i++) for (int j = 0; j < C; j++) { char tmp; cin >> tmp; if (tmp == '@') { maze[i][j] = 0; start.r = i; start.c = j; start.steps = 0; start.n = T; } if (tmp == '#') { maze[i][j] = -1; } if (tmp == '*') { maze[i][j] = 0; } if (tmp == '+') { maze[i][j] = 0; goal.r = i; goal.c = j; } } memset(visited, 0, sizeof(visited)); open[tail++] = start; visited[start.r][start.c][start.n] = 1; while (head < tail ){ Node tmp = open[head++]; if (tmp.c == goal.c && tmp.r == goal.r) { cout << "ok" << endl; cout << tmp.steps << endl; return 0; } for (int i = 0; i < 4; i++) { int r = tmp.r - dir[i][0]; int c = tmp.c - dir[i][1]; int n = tmp.n + maze[r][c]; if (0 <= r && r < R && 0 <= c && c < C && !visited[r][c][n] && n >= 0) { cout << "r:" << r << ", c:" << c << ", " << n << endl; open[tail++] = Node(r, c, n, tmp.steps + 1); visited[r][c][n] = 1; } } } return 0; }

浙公网安备 33010602011771号