POJ 3083 Children of the Candy Corn 解题报告
最短用BFS即可。关于左手走和右手走也很容易理解,走的顺序是左上右下。
值得注意的是,从起点到终点的右手走法和从终点到起点的左手走法步数是一样。
所以写一个左手走法就好了。贴代码,0MS
#include <cstdio> #include <cstring> #include <deque> using namespace std; int mp[45][45]; const int DIR[4][2]={ {0,-1},{-1,0},{0,1},{1,0} }; bool flag; void DFS(int x,int y,int dir,int step) { if(mp[x][y]) { flag=true; printf("%d ",step); } for(int i=3,a,b;i<=6;i++) { if(mp[ a=x+DIR[(i+dir)%4][0] ][ b=y+DIR[(i+dir)%4][1] ]>=0) DFS(a,b,(dir+i)%4,step+1); 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=1; mp[x][y]=-1; deque<Point> dq; dq.push_back(p); while(1) { p=dq.front(); dq.pop_front(); for(int i=0;i<4;i++) { q.step=p.step+1; q.x=p.x+DIR[i][0]; q.y=p.y+DIR[i][1]; if(mp[q.x][q.y]==0) { mp[p.x][q.y]=-1; dq.push_back(q); } if(mp[q.x][q.y]>0) { dq.clear(); printf("%d",q.step); return; } } } } int main() { int T; scanf("%d",&T); while(T--) { memset(mp,-1,sizeof(mp)); int w,h; int stax,stay,endx,endy; char str[50]; scanf("%d%d",&w,&h); for(int i=1;i<=h;i++) { scanf("%s",str+1); for(int k=1;k<=w;k++) { if(str[k]=='.') mp[i][k]=0; else if(str[k]=='S') { stax=i; stay=k; } else if(str[k]=='E') { endx=i; endy=k; } } } flag=false; mp[stax][stay]=0; mp[endx][endy]=1; DFS(stax,stay,1,1); flag=false; mp[stax][stay]=1; mp[endx][endy]=0; DFS(endx,endy,1,1); mp[endx][endy]=1; BFS(stax,stay); puts(""); } }