POJ 3083 Children of the Candy Corn 解题报告

时间:2021-02-15 09:16:30

最短用BFS即可。关于左手走和右手走也很容易理解,走的顺序是左上右下。

值得注意的是,从起点到终点的右手走法和从终点到起点的左手走法步数是一样。

所以写一个左手走法就好了。贴代码,0MS

#include <cstdio>
#include <cstring>
#include <deque>
using namespace std; int mp[][];
const int DIR[][]={ {,-},{-,},{,},{,} }; bool flag;
void DFS(int x,int y,int dir,int step)
{
if(mp[x][y])
{
flag=true;
printf("%d ",step);
}
for(int i=,a,b;i<=;i++)
{
if(mp[ a=x+DIR[(i+dir)%][] ][ b=y+DIR[(i+dir)%][] ]>=)
DFS(a,b,(dir+i)%,step+);
if(flag) return;
}
} struct Point
{
int x,y;
int step;
} p,q; void BFS(int x,int y)
{
p.x=x;
p.y=y;
p.step=;
mp[x][y]=-;
deque<Point> dq;
dq.push_back(p); while()
{
p=dq.front();
dq.pop_front(); for(int i=;i<;i++)
{
q.step=p.step+;
q.x=p.x+DIR[i][];
q.y=p.y+DIR[i][];
if(mp[q.x][q.y]==)
{
mp[p.x][q.y]=-;
dq.push_back(q);
}
if(mp[q.x][q.y]>)
{
dq.clear();
printf("%d",q.step);
return;
}
}
}
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(mp,-,sizeof(mp)); int w,h;
int stax,stay,endx,endy;
char str[]; scanf("%d%d",&w,&h);
for(int i=;i<=h;i++)
{
scanf("%s",str+);
for(int k=;k<=w;k++)
{
if(str[k]=='.')
mp[i][k]=;
else if(str[k]=='S')
{
stax=i;
stay=k;
}
else if(str[k]=='E')
{
endx=i;
endy=k;
}
}
} flag=false;
mp[stax][stay]=;
mp[endx][endy]=;
DFS(stax,stay,,); flag=false;
mp[stax][stay]=;
mp[endx][endy]=;
DFS(endx,endy,,); mp[endx][endy]=;
BFS(stax,stay);
puts("");
}
}