ZOJ 1649(BFS_F题)解题报告

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1649

---------------------------------------------------------------------------------------------------------------

题意:救援,找到从'r'到'a'的最短路径,'x'为警卫,通过需要耗时2,要求最短耗时。

思路:BFS+优先队列,明确的bfs的题目,wa了之后才意识到,简单队列无法求得正确解,原因在于queue是FIFO,之前的题目中实际默认了如下共识:先抵达的一定是要先出queue的最优解,然而由于本题有'x'的操作,要求通过后增加2,因此不能简单认为FIFO,所以应该采用优先队列,将step小的先出队,先判断。防止被较大step标记后不能访问的问题。

哦~对了,本题是多组数据输入输出,题目中叙述不明显,WA了好久~~

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int MAXN =400+10;
char a[MAXN][MAXN];
int vis[MAXN][MAXN];
int N =0;
int M =0;

int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};

struct State{
    int x;
    int y;
    int step;
};
State star;
int check(State s){
    int cx =s.x;
    int cy =s.y;
    if((cx>=0&&cy>=0)&&(cx<N&&cy<M)&&!vis[cx][cy]&&a[cx][cy]!='#'){
        return 1;
    }else{
        return 0;
    }
    
}

struct cmp1{
    bool operator() ( State a, State b ){return a.step>b.step;}  
};

int  bfs(State s){
    priority_queue<State,vector<State>,cmp1> q;
    State cur,cnext;
    s.step =0;
    q.push(s);
    while(!q.empty()){
        cur=q.top();
        q.pop();
        if(vis[cur.x][cur.y]) continue;
        vis[cur.x][cur.y]=1;
        
        if(a[cur.x][cur.y]=='r'){
            return cur.step;
        }
        for(int i=0;i<4;i++){
            cnext.x=cur.x+dir[i][0]; 
            cnext.y=cur.y+dir[i][1];
            if(check(cnext)){
                if(a[cnext.x][cnext.y]=='x'){
                    cnext.step=cur.step+2;
                }else{
                    cnext.step=cur.step+1;
                }
                q.push(cnext);
                //printf("cnext:%d,%d:%d\n",cnext.x,cnext.y,cnext.step);
            }
        }
    }
    return -1;
}


int main(void){
    while(scanf("%d %d",&N,&M)!=EOF){
    for(int i=0;i<N;i++){
        scanf("%s",a[i]);
    }

    for(int i=0;i<N;i++){
        for(int j=0;j<M;j++){
            vis[i][j] =0;
            if(a[i][j]=='a'){
                star.x=i;
                star.y=j;
            }
        }
    }

    int ans=bfs(star);
    if(ans!=-1){
        printf("%d\n",ans);
    }else{
        printf("Poor ANGEL has to stay in the prison all his life.\n");
    }
    
    }
    return 0;
}
View Code

 

posted @ 2018-01-29 15:03  caomp  阅读(99)  评论(0)    收藏  举报