BFS优先队列宽搜-2018湘潭大学程序设计竞赛F maze

这题关键是如何处理进传送门时间+3这个条件,因为传送后走的路线会对平常走的路线(用传统vis数组判断是否走过)造成影响,而且传送后有可能比不传送时间要短。因此思路是尽可能单独处理传送门的情况,或者将传送门的情况放在比较后的位置考虑,基于第二种思路,我是用了优先队列

AC代码如下:

#include<bits/stdc++.h>

#include<stdio.h>
using namespace std;
 
int n,m;
char a[304][304];
int vis[304][304];//访问过.和#
int vis2[304][304];//访问过传送门
int move1[4][2]={0,1,0,-1,1,0,-1,0};//move有些编译器会报错
int min1; 
  
struct point
{
    int x;
    int y;
    int step;
    bool operator<(const point a) const //优先队列默认是最大在上面,现在我们要每次把step最小放上面
    {
        return a.step<step;
    }
};
point cs[304][304];//传送门
 
 
int bfs(point begin,point end)
{
     priority_queue<point>que;
    que.push(begin);
    point cur;//当前层节点
   
     
    while(!que.empty())//宽搜模板
    {
        cur=que.top();
        que.pop();
        point temp;
        //if(a[cur.x][cur.y]=='#')return -1;//一开始以为起点和终点可能有陷阱,实际上不可能
        if(cur.x==end.x&&cur.y==end.y)
        {
  
        min1=min(min1,cur.step);//取最小值,也可直接return cur.step
}
       
        temp.x=cs[cur.x][cur.y].x;
                temp.y=cs[cur.x][cur.y].y;
            if(vis[temp.x][temp.y]==0&&vis2[cur.x][cur.y]==2&&a[cur.x][cur.y]!='#'&&a[temp.x][temp.y]!='#')
            {
                 
                temp.step=cur.step+3;
                que.push(temp);
                vis2[cur.x][cur.y]=1;
                //vis[temp.x][temp.y]=1;// 
            }


        for(int i=0;i<4;i++)
        {
            temp.x=cur.x+move1[i][0];
            temp.y=cur.y+move1[i][1];
             //cout<<temp.x<<" "<<temp.y<<" "<<temp.step<<endl;
            if(temp.x>=0&&temp.x<n&&temp.y>=0&&temp.y<m&&vis[temp.x][temp.y]==0&&a[temp.x][temp.y]!='#')
            {
                temp.step=cur.step+1;
                vis[temp.x][temp.y]=1;
                que.push(temp);
            }
             
             
        }
         
         
    }
    if(min1!=1e9)
    return min1;
    else
    return -1;//查询完毕,队列为空,返回-1
     
 
}
 
 
int main()
{
        int q;
    while(cin>>n>>m>>q)
    {
    memset(vis,0,sizeof(vis));
     memset(cs,0,sizeof(cs));
     memset(vis2,0,sizeof(vis2));
      min1=1e9;
      
    point begin,end;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cin>>a[i][j];
            if(a[i][j]=='S')
            {
                begin.x=i;
                begin.y=j;
                 
                begin.step=0;
                vis[begin.x][begin.y]=1;
            }
            if(a[i][j]=='T')
            {
                end.x=i;
                end.y=j;
            }
        }
    }
    for(int j=0;j<q;j++)
    {
        int a,b,c,d;
        cin>>a>>b;
        cin>>cs[a][b].x>>cs[a][b].y;
        vis2[a][b]=2;
    }
   cout<<bfs(begin,end)<<endl; 
    }
}

猜你喜欢

转载自blog.csdn.net/zjyang12345/article/details/80113905