hdu1026 优先队列+广搜

6 篇文章 0 订阅
5 篇文章 0 订阅
/*这个题调试了很长时间,不过一次AC,感觉很爽!*/ 
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;
struct node
{
       int x,y;
       int step;
       friend  bool operator<(node a,node b)//搜了一下这个事优先队列的出列次序按照step由大到小的顺序出列 
       {
               return b.step<a.step;
       }
       
};
const int N=102;
int map[N][N];
int flag[N][N];
int n,m;
int blood[N][N]; 
int ds[4][2]={0,1,1,0,0,-1,-1,0};//表示四个方向 
int judge(int x,int y)
{
       if(x>=0&&x<=n-1&&y>=0&&y<=m-1&&map[x][y]!=-1)
       return 1;
       return 0;
}
int bfs()
{
       priority_queue<node> qu;//优先队列 
       node pre,cur,next;
       int xx,yy,step;
       pre.x=0;
       pre.y=0;
       pre.step=0;
       map[0][0]=-1;
       qu.push(pre);
       while(!qu.empty())
       {
              // cout<<"you are a girl!"<<endl;  //用来调试的代码 
               cur=qu.top();
               qu.pop();
               for(int i=0;i<4;i++)
               {
                      next.x=xx=cur.x+ds[i][0];
                      next.y=yy=cur.y+ds[i][1];
                      next.step=step=cur.step+map[xx][yy]+1;//后面多个map[xx][yy]很关键 
                      
                      if(judge(xx,yy))
                      {
                           // cout<<"xx="<<xx<<"yy="<<yy<<endl;          
                            map[xx][yy]=-1;
                            flag[xx][yy]=i+1;
                            if(xx==n-1&&yy==m-1)
                            { 
                                  //  cout<<"flag[xx][yy]="<<flag[xx][yy]<<endl;
                                    return step;
                                      
                            }
                            
                            qu.push(next);
                      }
               }
       }
       return -1;
}
int step;
void  P(int x,int y)//输出路径,其中flag是联系的桥梁 
{     // cout<<"("<<x<<","<<y<<")"<<endl; 
      // cout<<flag[x][y]<<endl;
       if(flag[x][y]==0) return ;
       int  xx=x-ds[flag[x][y]-1][0];
       int  yy=y-ds[flag[x][y]-1][1];
       P(xx,yy);
       
       printf("%ds:(%d,%d)->(%d,%d)\n",++step,xx,yy,x,y);//先到达然后判断需不需要fight 
       while(blood[x][y]--) printf("%ds:FIGHT AT (%d,%d)\n",++step,x,y);
       
}
int main()
{
       int count=0;
       char str[N];
       while(cin>>n>>m)
       {
              memset(flag,0,sizeof(flag));
              memset(blood,0,sizeof(blood));
              memset(map,0,sizeof(map));
              for(int i=0;i<n;i++)
              {
                    scanf("%s",str);  
                    for(int j=0;j<m;j++)
                    {
                          if(str[j]=='X') map[i][j]=-1;
                          else if(str[j]=='.') map[i][j]=0;
                          else map[i][j]=blood[i][j]=str[j]-'0';
                    }
              }  
              count=bfs();                                               
              if(count!=-1)
              {
                   // printf("It takes %d seconds to reach the target position, let me show you the way.\n",count);
                    printf("It takes %d seconds to reach the target position, let me show you the way.\n",count);
                    step=0; 
                   
                    P(n-1,m-1);
                   
                    
              }     
              else printf("God please help our poor hero.\n");
              printf("FINISH\n");
       }
       return 0;
}                            
       
        


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值