http://bailian.openjudge.cn/practice/4115?lang=en_US
一道bfs 题目,与普通的不同的是 要记录每条路走过的查克拉的数量,如果第一次走过某个点的查克拉记录下来,如果下次还走到这里但是他的查克拉数量大于第一次的数量,那么就需要更新一下.
例如:
#*@*# **#*# ##*##//在中间的位置时需要更新 #*#*# **+** 代码:
#include<bits/stdc++.h>
using namespace std;
char maze[200][200];
int vis[205][205];
int pre[205][205];
struct node{
int x,y,k;
int step;
};
int n,m,k,ex,ey;
int d[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
int bfs(int x, int y){
queue<node> q;
node t;
t.x = x;
t.y = y;
t.k = k;
t.step = 0;q.push(t);
while(!q.empty()){
node f = q.front();
q.pop();
if(maze[f.x][f.y] == '+'){ return f.step;}
// cout << maze[f.x][f.y] << endl;
node next;
for(int i = 0; i < 4;i++){
next.x = f.x + d[i][0];
next.y = f.y + d[i][1];
next.k = f.k;//每条路查克拉数量if(next.x >= 0&&next.x < n&&next.y >=0&&next.y < m){
if(vis[next.x][next.y] == 0){//没有来过 直接记录
vis[next.x][next.y] = 1;
next.step = f.step + 1;
next.k = f.k;
if(maze[next.x][next.y] == '#'){
if(next.k <= 0) continue;
next.k = f.k - 1;
}
pre[next.x][next.y] = next.k;
q.push(next);
}
else if(vis[next.x][next.y] == 1){//第一次来过这里
if(f.k > pre[next.x][next.y]){
// pre[next.x][next.y] = f.k;
next.k = f.k;
next.step = f.step + 1;
if(maze[next.x][next.y] == '#'){
next.k = f.k- 1;
}
pre[next.x][next.y] = next.k;
q.push(next);
}
}}
}
}
return -1;
}
int main()
{scanf("%d%d%d",&n,&m,&k);
for(int i = 0; i < n; i++){
scanf("%s",maze[i]);
}
int ans = 0;
for(int i = 0; i < n ;i++){
for(int j = 0; j < m; j++){
if(maze[i][j] == '@'){
ans = bfs(i,j);
break;
}
}
}printf("%d\n",ans);
}