CSU - 1726 你经历过绝望吗?两次!(优先队列BFS)

题目大意:题目戳我

     翻译过来就是“猪坚强”走出去,但是经过“."时不需要花费步数,而经过“*”需要花费一步,“#”表示障碍。

题目思路:

     因为步数不一样,考虑用优先队列来保存经过的步数,每次步数小的先出队;

收获:

     在结构体里重载优先队列的运算符时,只能对"<"号进行重载,不然会报错;

struct COO
{
     int x,y;
     int num;
     friend bool operator<(COO a,COO b)
     {
          return a.num>b.num;
     }//步数少的优先
}start,nxt,mid;

   如果想要步数大的优先出来:

struct COO
{
     int x,y;
     int num;
     friend bool operator<(COO a,COO b)
     {
          return a.num<b.num;
     }//步数大的优先
}start,nxt,mid;

题目代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 105

using namespace std;

int dx[4]={1,0,-1,0};
int dy[4]={0,-1,0,1};
int vis[maxn][maxn];
struct COO
{
     int x,y;
     int num;
     friend bool operator<(COO a,COO b)
     {
          return a.num>b.num;
     }//步数少的优先
}start,nxt,mid;
priority_queue<COO>q;

int main(void)
{
     int t,m,n;
     char ch[maxn][maxn];
     int a,b;
     int flag;
     scanf("%d",&t);
     while(t--)
     {
          while(!q.empty())
               q.pop();
          flag=1;
          memset(vis,0,sizeof(vis));
          memset(ch,0,sizeof(ch));
          //初始化
          scanf("%d%d",&n,&m);
          for(int i=0;i<n;i++)
          {
               scanf("%s",ch[i]);
          }
          for(int i=0;i<n;i++)
          {
               for(int j=0;j<m;j++)
                    if(ch[i][j]=='@')
                    {
                         a=i;
                         b=j;//第a行第b列
                    }
          }
          //printf("a: %d,b: %d\n",a,b);
          start.x=a;start.y=b;
          start.num=0;
          q.push(start);
          vis[a][b]=1;
          while(!q.empty())
          {
               mid=q.top();
               q.pop();
               if(mid.x==0||mid.x==(n-1)||mid.y==0||mid.y==(m-1))
               {
                    //printf("mmmm\n");
                    flag=0;
                    printf("%d\n",mid.num);
                    break;
                         //goto mm;
               }
               for(int i=0;i<4;i++)
               {
                    int nx=mid.x+dx[i];
                    int ny=mid.y+dy[i];
                    //printf("mid.x: %d,mid.y: %d\n",mid.x,mid.y);
                    //printf("nx: %d,ny: %d\n",nx,ny);
                    if(nx>=0&&nx<n&&ny>=0&&ny<m&&!vis[nx][ny]&&ch[nx][ny]!='#')
                    {
                         if(ch[nx][ny]=='.')//步数+0
                              nxt.num=mid.num;
                         else if(ch[nx][ny]=='*')//步数+1
                              nxt.num=mid.num+1;
                         nxt.x=nx;
                         nxt.y=ny;
                         vis[nx][ny]=1;
                         q.push(nxt);
                    }
               }
          }
          if(flag)
               printf("-1\n");
     }
}

呼呼

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值