0
点赞
收藏
分享

微信扫一扫

优先队列 bfs Angel was caught by theMOLIGPY!


Problem L

Time Limit : 2000/1000ms(Java/Other)   Memory Limit :65536/32768K (Java/Other)

Total Submission(s) :23   Accepted Submission(s) : 6

Problem Description

Angel was caught bytheMOLIGPY! He was put in prison by Moligpy. The prison is described as a N *M(N, M &lt;= 200) matrix. There are WALLs, ROADs, and GUARDs intheprison.<br><br>Angel's friends want to save Angel. Their taskis:approach Angel. We assume that &quot;approach Angel&quot; is to gettothe position where Angel stays. When there's a guard in the grid, we mustkillhim (or her?) to move into the grid. We assume that we moving up, down,right,left takes us 1 unit time, and killing a guard takes 1 unit time, too.And weare strong enough to kill all the guards.<br><br>You havetocalculate the minimal time to approach Angel. (We can move only UP, DOWN,LEFTand RIGHT, to the neighbor grid within bound, of course.)<br>

 

 

Input

First line containstwointegers stand for N and M.<br><br>Then N lines follows, everylinehas M characters. "." stands for road, "a" standsforAngel, and "r" stands for each of Angel'sfriend.<br><br>Process to the end of the file.<br>

 

 

Output

For each test case,yourprogram should output a single integer, standing for the minimal timeneeded.If such a number does no exist, you should output a line containing"PoorANGEL has to stay in the prison all his life." <br>

 

 

Sample Input

7 8

#.#####.

#.a#..r.

#..#x...

..#..#.#

#...##..

.#......

........

 

 

Sample Output

13

题目分析:

3这题坑了我好久,第一,这题的天使的朋友不止一个。第二,scanf的知识不足。

天使的朋友虽然不止一个,但是天使就一个,我们可以道着找,从天使找朋友。

接下来一篇时间超时的代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,t,ans=0;
char mapp[205][205];
int flag[205][205]={0};
int dx[4]={-1,1,0,0},  
    dy[4]={0,0,1,-1};
int bfs(int x1,int y1)
{
 
    int i,j,head=0,tail=1,x,y;
    flag[x1][y1]=1;
    intxx[100000],yy[100000],ti[100000];
    xx[1]=x1;
    yy[1]=y1;
    ti[1]=0;
    do
    {
        head++;
 
       if(mapp[xx[head]][yy[head]]=='r')
        {
            ans=ti[head];
            return 0;
        }
        else
        for(i=0;i<4;i++)
        {
 
            x=xx[head]+dx[i];
            y=yy[head]+dy[i];
           if(x>=0&&x<n&&y>=0&&y<m&&flag[x][y]==0)
            {
               if(mapp[x][y]=='.'||mapp[x][y]=='r')
                {
                tail++;
                flag[x][y]=1;
                xx[tail]=x;
                yy[tail]=y;
                ti[tail]=ti[head]+1;
                }
                elseif(mapp[x][y]=='x')
                {
                    tail++;
                flag[x][y]=1;
                xx[tail]=x;
                yy[tail]=y;
                ti[tail]=ti[head]+2;
                }
 
            }
        }
    }while(head<tail);
    return 0;
}
int main()
{
    int i,j;
  while(scanf("%d%d",&n,&m))
    {
        memset(flag,0,sizeof(flag));
        int x,y;
       for(i=0;i<n;i++)
       {
          scanf("%s",&mapp[i]);
           for(j=0;j<m;j++)
            {
                if(mapp[i][j]=='#')
               {flag[i][j]=1;}
            }
       }
       for(i=0;i<n;i++)
        for(j=0;j<m;j++)
           if(mapp[i][j]=='a')
            bfs(i,j);
            if(ans)
                cout<<ans<<endl;
            else
               cout<<"Poor ANGEL has to stay in the prison all hislife."<<endl;
    }
 
    return 0;
}

以为没使用队列的原因:

接下来队列的代码:

#include<bits/stdc++.h>
 
using namespace std;
 
int n,m,ans=0;
 
char mapp[205][205];
 
int vis[205][205]={0};
 
int dx[4]={-1,1,0,0},
 
   dy[4]={0,0,1,-1};
 
struct node
 
{
 
    intx,y,step;
 
 
 
}a,b;
 
int bfs(int x1,int y1)
 
{
 
   queue<node>q;
 
    a.x=x1;
 
    a.y=y1;
 
   vis[a.x][a.y]=1;
 
    a.step=0;
 
    q.push(a);
 
   while(!q.empty())
 
    {
 
       a=q.front();
 
        q.pop();
 
       if(mapp[a.x][a.y]=='r')
 
        {
 
           ans=a.step;
 
           return 0;
 
        }
 
        else
 
        {for(inti=0;i<4;i++)
 
        {
 
           b.x=a.x+dx[i];
 
           b.y=a.y+dy[i];
 
          if(!vis[b.x][b.y]&&b.x>=0&&b.x<n&&b.y>=0&&b.y<m)
 
            {
 
               vis[b.x][b.y]=1;
 
              if(mapp[b.x][b.y]=='.'||mapp[b.x][b.y]=='r')
 
                   b.step=a.step+1;
 
               elseif(mapp[b.x][b.y]=='x')
 
                    b.step=a.step+2;
 
               q.push(b);
 
            }
 
        }
 
        }
 
     }
 
    return 0;
 
}
 
int main()
 
{
 
    int i,j;
 
 while(scanf("%d%d",&n,&m))
 
    {
 
        ans=0;
 
       memset(vis,0,sizeof(vis));
 
        int x,y;
 
      for(i=0;i<n;i++)
 
       {
 
         scanf("%s",&mapp[i]);
 
          for(j=0;j<m;j++)
 
            {
 
               if(mapp[i][j]=='#')
 
               {vis[i][j]=1;}
 
            }
 
       }
 
      for(i=0;i<n;i++)
 
       for(j=0;j<m;j++)
 
          if(mapp[i][j]=='a')
 
             bfs(i,j);
 
 
 
           if(ans)
 
              cout<<ans<<endl;
 
            else
 
              cout<<"Poor ANGEL has to stay in the prison allhislife."<<endl;
 
    }
 
 
 
    return 0;
 
}

还是超时:

 

以为没用优先队列,上网学习优先队列:

#include<bits/stdc++.h>
 
using namespace std;
 
int n,m,ans=0;
 
#define M 205
 
char mapp[M][M];
 
int vis[M][M]={0};
 
int dx[4]={0,0,1,-1},
 
   dy[4]={1,-1,0,0};
 
struct node
 
{
 
    intx,y,step;
 
    friend booloperator< (constnode c,const node d) //第一次优先队列
 
    {
 
        returnc.step>d.step;
 
    }
 
};
 
int bfs(int x1,int y1)
 
{
 
    node a,b;
 
   priority_queue<node>q;
 
    a.x=x1;
 
    a.y=y1;
 
   memset(vis,0,sizeof(vis));
 
    vis[a.x][a.y]=1;
 
    a.step=0;
 
    q.push(a);
 
   while(!q.empty())
 
    {
 
       a=q.top();  //小小不同
 
        q.pop();
 
       if(mapp[a.x][a.y]=='r')
 
        {
 
           ans=a.step;
 
           return 0;
 
        }
 
 
 
        for(inti=0;i<4;i++)
 
        {
 
           b.x=a.x+dx[i];
 
           b.y=a.y+dy[i];
 
          if(mapp[b.x][b.y]!='#'&&!vis[b.x][b.y]&&b.x>=0&&b.x<n&&b.y>=0&&b.y<m)
 
            {
 
               vis[b.x][b.y]=1;
 
              if(mapp[b.x][b.y]=='.'||mapp[b.x][b.y]=='r')
 
                    b.step=a.step+1;
 
               else if(mapp[b.x][b.y]=='x')
 
                    b.step=a.step+2;
 
               q.push(b);
 
            }
 
        }
 
     }
 
    return 0;
 
}
 
int main()
 
{
 
    int i,j;
 
  while(scanf("%d%d",&n,&m))
 
    {
 
        ans=0;
 
        int x,y;
 
      for(i=0;i<n;i++)
 
       {
 
       scanf("%s",&mapp[i]);
 
          for(j=0;j<m;j++)
 
            {
 
               if(mapp[i][j]=='a')
 
                  {x=i;y=j;}
 
            }
 
       }
 
 
 
           bfs(x,y);
 
 
 
           if(ans)
 
               cout<<ans<<endl;
 
            else
 
              cout<<"Poor ANGEL has to stay in the prison allhislife."<<endl;
 
    }
 
 
 
    return 0;
 
}

 

结果还是超时:

弄了好久,才知道是循环输入scanf的问题:

这个要从scanf函数的返回值说起。
比如scanf("%d", &n);有如下情况:
1. 当输入为一个整数时,读取到n,scanf返回值是1(表示成功读取了一个数),ok,继续执行
2. 当输入为EOF(通常切的题目有多组数据,会使用EOF表示输入结束),这时,没有读取输入到n,scanf返回值是-1,所以您的代码==1就不成立,所以会跳出循环。而如果是while(scanf("%d",&n))的话,即等价于while(-1),显然还会继续循环,所以超时。
所以可以有以下用法:
1. while(scanf("%d", &n) == 1)
2. while(scanf("%d", &n) != EOF)
3. while(~scanf("%d", &n)) 当输入为EOF时,-1求反为0哦,所以也可以。

接下来优先队列AC代码:

#include<bits/stdc++.h>
 
using namespace std;
 
int n,m,ans=0;
 
#define M 205
 
char mapp[M][M];
 
int vis[M][M]={0};
 
int dx[4]={0,0,1,-1},
 
   dy[4]={1,-1,0,0};
 
struct node
 
{
 
    intx,y,step;
 
    friend booloperator< (constnode c,const node d) //第一次优先队列
 
    {
 
        returnc.step>d.step;
 
    }
 
};
 
int bfs(int x1,int y1)
 
{
 
    node a,b;
 
   priority_queue<node>q;
 
    a.x=x1;
 
    a.y=y1;
 
   memset(vis,0,sizeof(vis));
 
   vis[a.x][a.y]=1;
 
    a.step=0;
 
    q.push(a);
 
   while(!q.empty())
 
    {
 
       a=q.top();  //小小不同
 
        q.pop();
 
       if(mapp[a.x][a.y]=='r')
 
        {
 
           ans=a.step;
 
           return 0;
 
        }
 
 
 
        for(inti=0;i<4;i++)
 
        {
 
           b.x=a.x+dx[i];
 
           b.y=a.y+dy[i];
 
          if(mapp[b.x][b.y]!='#'&&!vis[b.x][b.y]&&b.x>=0&&b.x<n&&b.y>=0&&b.y<m)
 
            {
 
               vis[b.x][b.y]=1;
 
              if(mapp[b.x][b.y]=='.'||mapp[b.x][b.y]=='r')
 
                   b.step=a.step+1;
 
               elseif(mapp[b.x][b.y]=='x')
 
                    b.step=a.step+2;
 
               q.push(b);
 
            }
 
        }
 
     }
 
    return 0;
 
}
 
int main()
 
{
 
    int i,j;
 
  scanf("%d%d",&n,&m)!=EOF   
 
{
 
        ans=0;
 
        int x,y;
 
      for(i=0;i<n;i++)
 
       {
 
       scanf("%s",&mapp[i]);
 
          for(j=0;j<m;j++)
 
            {
 
               if(mapp[i][j]=='a')
 
                  {x=i;y=j;}
 
            }
 
       }
 
 
 
           bfs(x,y);
 
 
 
           if(ans)
 
              cout<<ans<<endl;
 
            else
 
              cout<<"Poor ANGEL has to stay in the prison allhislife."<<endl;
 
    }
 
 
 
    return 0;
 
}

举报

相关推荐

0 条评论