poj 1955
题目大意:给出地图的长和宽,和骑士的起始位置和终点位置,求出最少的移动步数
解决: 双广,由于地图比较大比较适合双搜
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; int n,sx,sy,ex,ey; bool vis[2][305][305]; int dx[]={2,2,-2,-2,1,1,-1,-1}; int dy[]={1,-1,1,-1,2,-2,2,-2}; struct node { int x,y,s; node(){} node(int xx,int yy,int ss):x(xx),y(yy),s(ss){} }; bool check(int no,const node & t) { if(t.x>=0 && t.x<n && t.y >= 0 && t.y < n && !vis[no][t.x][t.y])return true; return false; } int dbfs() { queue<node> q[2]; q[0].push(node(sx,sy,0)); q[1].push(node(ex,ey,0)); vis[0][sx][sy]=1; vis[1][ex][ey]=1; int step=0; node thisnode,nextnode; while(!q[0].empty() || !q[1].empty()) {/*nowg表示这次轮到那个扩展了,起始为0,表示是轮起始端扩展 当起始端扩展完毕,第一个队列所有步子为step的结点全部出队列,相当于 走了一步,第二次轮末位端扩展了,扩展完毕后,第二个队列的步子为step的结点 全部出队列,相当于从末尾走了一步 */ int nowg=step&1,cnt=q[nowg].size(); while(cnt--) { thisnode=q[nowg].front(); q[nowg].pop(); for(int i=0;i<8;i++) { nextnode=node(thisnode.x+dx[i],thisnode.y+dy[i],step+1); if(!check(nowg,nextnode))continue; //只是判断的是对方已经走过的路径中是否包含要走的位置 if(vis[nowg^1][nextnode.x][nextnode.y])return step+1; vis[nowg][nextnode.x][nextnode.y]=1; q[nowg].push(nextnode); } } step++; } } int main() { int icase; scanf("%d",&icase); while(icase--) { memset(vis,0,sizeof(vis)); scanf("%d%d%d%d%d",&n,&sx,&sy,&ex,&ey); if(sx==ex && sy==ey)printf("0\n"); else printf("%d\n",dbfs()); } system("pause"); return 0; }