优先队列解决广搜的问题

点击打开链接

题目大意:从p走到g,如果是#,则不能走,如果是“.”,则需要时间加1,如果是“x”,则时间加2,如果是“X”,则时间加3,问从p到g最少需要多少时间,如果不能到达,则输出-1。

方法:用一个优先队列,每次从里面选出时间最少时间,然后算走到四个方向的时间。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
struct pp
{
    int x,y;
    int step;
    pp(){}
    pp(int xx, int yy, int tt): x(xx),y(yy),step(tt){}
    bool operator < (const pp &a)const{
        return step > a.step;
    }
};
priority_queue<pp> qq;
int d[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
bool flag[60][60];
int main(){
    int T, cas, i, n, m, j;
    int stx, sty, enx, eny;
    char ch[60][60];
    scanf("%d", &T);
    for(cas = 1;  cas <= T; cas++){
        scanf("%d%d",&n,&m);
        getchar();
        memset(flag, 0, sizeof(flag));
        for(i = 0; i < n; i++)
            scanf("%s",ch[i]);
        for(i = 0; i < n; i++){
            for(j = 0 ;j < m; j++){
                if(ch[i][j] == 'p'){
                    stx = i;  sty = j;
                }
                else if(ch[i][j] == 'g'){
                    enx = i; eny = j;
                }
            }
        }
        //因为是多组数据,所以每一次都要用这样的方式清空
        while(!qq.empty()){
            qq.pop();
        }
        qq.push(pp(stx, sty, 0));
        flag[stx][sty] = 1;
        int cont = 0;
        pp cur;
        bool temp = 0;
        while(!qq.empty()){
            cur = qq.top();
            cont = cur.step;
            //用qq.top()去走,则需要将首元素去掉,然后再走
            qq.pop();
            for(i = 0; i < 4; i++){
                int xxx = cur.x + d[i][0];
                int yyy = cur.y + d[i][1];
                if(xxx < 0 || xxx >= n)   continue;
                if(yyy < 0 || yyy >= m)   continue;
                if(ch[xxx][yyy] == '#')  continue;
                if(flag[xxx][yyy] == 1)  continue;
                if(xxx == enx && yyy == eny){
                    cont += 1;
                    temp = 1;
                    break;
                }
                if(ch[xxx][yyy] == 'x')
                    qq.push(pp(xxx, yyy, cont+2));
                else if(ch[xxx][yyy] == '.')
                    qq.push(pp(xxx, yyy, cont+1));
                else if(ch[xxx][yyy] == 'X')
                    qq.push(pp(xxx, yyy, cont+3));
                flag[xxx][yyy] = 1;
            }
            if(temp == 1)
                break;
        }
        if(!temp)
            printf("-1\n");
        else
            printf("%d\n", cont);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值