题目和题目解释都在上一篇博客里了
点这里
这题终于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;
}
所以相差的时间其实就是 用来搜边界处的点了