NYOJ 284 优先队列 搜索

题意:图中Y代表起点,T代表终点,S代表铁墙,不可被击毁也不可被通过,B代表木墙,可以被击毁,击毁后可以通过,R代表河流,不可击毁也不可通过,E代表可通过。

击毁木墙会消耗一步,问最少多少步能从起点走到终点。

 
#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
//优先队列广搜
const int maxn=305;
const int INF=0x3f3f3f3f;
char map[maxn][maxn];
int vis[maxn][maxn];
int dis[4][2]= {{0,1},{0,-1},{1,0},{-1,0}};
int N,M;
int star_x,star_y;
int end_x,end_y;
struct node
{
    int x;
    int y;
    int time;
    friend bool operator <(node n1,node n2)
    {
        return n1.time>n2.time;
    }
};

int BFS(int star_x,int star_y)
{
    priority_queue<node>q;
    node star;
    star.time=0;
    star.x=star_x;
    star.y=star_y;
    memset(vis,0,sizeof(vis));
    vis[star_x][star_y]=1;
    q.push(star);
    while(!q.empty())
    {
        star=q.top();
        q.pop();
        for(int i=0; i<4; i++)
        {
            node end;
            end=star;
            end.x+=dis[i][0];
            end.y+=dis[i][1];

            if(end.x>=1&&end.x<=N&&end.y>=1&&end.y<=M&&vis[end.x][end.y]==0&&map[end.x][end.y]!='S'&&map[end.x][end.y]!='R')
            {
//                printf("%d %d\n",end.x,end.y);
                if(map[end.x][end.y]=='E')
                {
                    end.time++;
                    vis[end.x][end.y]=1;
                    q.push(end);
                }
                else if(end.x==end_x&&end.y==end_y)
                {
                    end.time++;
                    return end.time;
                }
                else if(map[end.x][end.y]=='B')
                {
                    end.time++;
                    end.time++;//这里做了改动
                    vis[end.x][end.y]=1;
                    q.push(end);
                }
            }
        }
    }
//    for(int i=1; i<=N; i++)
//    {
//        for(int j=1; j<=M; j++)
//            printf("%c ",map[i][j]);
//        printf("\n");
//    }
    return -1;
}
int main()
{
    while(~scanf("%d%d",&N,&M)&&N&&M)
    {
        for(int i=1; i<=N; i++)
        {
            getchar();
            for(int j=1; j<=M; j++)
            {
                scanf("%c",&map[i][j]);
                if(map[i][j]=='Y')
                {
                    star_x=i;
                    star_y=j;//这里可能有问题
                }
                else if(map[i][j]=='T')
                {
                    end_x=i;
                    end_y=j;
                }
            }
//            getchar();
        }
        printf("%d\n",BFS(star_x,star_y));
    }
    return 0;
}        


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值