SPOJ Escape from Jail Again

题目和题目解释都在上一篇博客里了
点这里
这题终于AC了。(〃‘▽’〃)
开始做的时候bfs里连续四五个continue的确会超时,然后尽量把continue次数变少,还是超时。

if(ontheside(newx,newy))
            {
                return (2+top.step);
            }

就一处,这里不加就超时了。。。

 if(top.x<0||top.x>=m||top.y<0||top.y>=n)
        {
           printf("%d\n",top.step);
           return ;
        }

对比一下常规的写法,搜索到边界处再往下搜一个单位然后回到判断条件出输出。

但是假如你已经下一步搜到边界处了,那你再下一步就不需要再去搜了,因为到达边界处只要加1就出迷宫了

bool judge(int x,int y)
{
    return x>=0&&x<m&&y>=0&&y<n;
}

这样又可以减少时间复杂度。
也不说坑吧,其实蛮有道理的

//     Time(ms) 10               Mem(MB) 4.4                Lang C++
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string.h>
#include<cstdlib>
#include<cstring>
#include<math.h>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
using namespace std;
char mp[105][105];
int book[105][105][2];
int NEXT[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int m,n;
struct node
{
    int x,y,step,f;
};
bool isOnTheSides(int x, int y)
{
    return x==0||x==m-1||y==0||y==n-1;
}
bool judge(int x,int y)
{
    return x>=0&&x<m&&y>=0&&y<n;
}
queue<node>q;
int bfs(int x,int y)
{
    node F;
    while(!q.empty())
    {
        q.pop();
    }
    F.x=x;
    F.y=y;
    F.step=0;
    F.f=0;
    if(isOnTheSides(x,y))
    {
        return 1;
    }
    q.push(F);
    book[x][y][0]=1;
    while(!q.empty())
    {
        node top=q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            int newx=top.x+NEXT[i][0];
            int newy=top.y+NEXT[i][1];
            if(judge(newx,newy)&&mp[newx][newy]!='W'&&book[newx][newy][top.f]==0)
        {
            if(mp[newx][newy]=='D'&&top.f==0)
                continue;
            book[newx][newy][top.f]=1;
            int newf=top.f;
            if(mp[newx][newy]=='O')
            {
                newf=1;
                book[newx][newy][1]=1;
            }
            else if(mp[newx][newy]=='C')
            {
                newf=0;
                book[newx][newy][0]=1;
            }
            if(isOnTheSides(newx,newy))
            {
                return (2+top.step);//加入下一个点是边界点,直接输出step+2
            }
            node now;
            now.x=newx;
            now.y=newy;
            now.f=newf;
            now.step=top.step+1;
            q.push(now);
          }
        }
    }

    return -1;

}
int main()
{
   while(~scanf("%d%d",&m,&n))
   {
       if(m==-1&&n==-1)
          break;
       memset(book,0,sizeof(book));
      int X,Y;
       for(int i=0;i<m;i++)
     {
       for(int j=0;j<n;j++)
       {
           cin>>mp[i][j];
           if(mp[i][j]=='H')
           {
               X=i;
               Y=j;
           }
       }
      }
      cout<<bfs(X,Y)<<endl;
   }
    return 0;
}

所以相差的时间其实就是 用来搜边界处的点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值