poj 2243 Knight Moves

// 题意:图的大小8*8,可以向 8 个方向移动,求起点到终点的最短移动距离 
#include <iostream> // BFS
#include <string>

using namespace std;
const int L=8;
int q[L*L],vis[L][L],dist[L][L];
const int dx[]={-1,-2,-2,-1,1,2,2,1};
const int dy[]={-2,-1,1,2,2,1,-1,-2};
int sx,sy,tx,ty;
void bfs()
{
vis[sx][sy]=1;
dist[sx][sy]=0;
q[0]=sx*L+sy;
int front=0,rear=1;
while(front<rear)
{
int z=q[front];
int x=z/L,y=z%L;
if(x==tx&&y==ty)
{
printf("To get from %c%d to %c%d takes %d knight moves.\n",sx+'a',sy+1,tx+'a',ty+1,dist[tx][ty]);
break;
}
for(int d=0;d<8;++d)
{
int newx=x+dx[d];
int newy=y+dy[d];
int newz=newx*L+newy;
if(newx>=0&&newx<L&&newy>=0&&newy<L&& !vis[newx][newy] )
{
vis[newx][newy]=1;
q[rear]=newz;
dist[newx][newy]=dist[x][y]+1;
rear++;
}
}
front++;
}
}
int main()
{
char ch[10];
while(gets(ch))
{
sx=ch[0]-'a';
sy=ch[1]-'1';
tx=ch[3]-'a';
ty=ch[4]-'1';
memset(vis,0,sizeof(vis));
bfs();
}
return 0;
}

 

 

 

 

双向BFS
#include <iostream>        // 双向BFS
#include <string>
using namespace std;
const int L=8;
int q1[L*L],q2[L*L],vis[L][L],dist1[L][L],dist2[L][L];
const int dx[]={-1,-2,-2,-1,1,2,2,1};
const int dy[]={-2,-1,1,2,2,1,-1,-2};
int sx,sy,tx,ty;
void bfs()
{
if(sx==tx&&sy==ty)
{
printf("To get from %c%d to %c%d takes 0 knight moves.\n",sx+'a',sy+1,tx+'a',ty+1);
return ;
}
vis[sx][sy]+=1;
dist1[sx][sy]=0;
q1[0]=sx*L+sy;
vis[tx][ty]+=2;
dist2[tx][ty]=0;
q2[0]=tx*L+ty;
int front1=0,rear1=1,front2=0,rear2=1,ok=0;
while(front1<rear1||front2<rear2)
{

//正向搜索
if(front1<rear1)
{
int z=q1[front1];
int x=z/L,y=z%L;
for(int d=0;d<8;++d)
{
int newx=x+dx[d];
int newy=y+dy[d];
int newz=newx*L+newy;
if(newx>=0&&newx<L&&newy>=0&&newy<L)
{
if( vis[newx][newy] == 0 )
{
vis[newx][newy] = 1 ; // 正向搜索标记为 1
q1[rear1]=newz;
dist1[newx][newy]=dist1[x][y]+1;
rear1++;
}
else if( vis[newx][newy] == 2 ) // 说明正向和反向搜索发生相遇
{
dist1[newx][newy]=dist1[x][y]+1;
printf("To get from %c%d to %c%d takes %d knight moves.\n",sx+'a',sy+1,tx+'a',ty+1,dist1[newx][newy]+dist2[newx][newy]);
ok=1;
break;
}
}
}
front1++;

if(ok)
break;
}

//反向搜索
if(front2<rear2)
{
int z=q2[front2];
int x=z/L,y=z%L;
for(int d=0;d<8;++d)
{
int newx=x+dx[d];
int newy=y+dy[d];
int newz=newx*L+newy;
if(newx>=0&&newx<L&&newy>=0&&newy<L)
{
if( vis[newx][newy] == 0 )
{
vis[newx][newy] = 2 ; // 反向搜索标记为 2
q2[rear2]=newz;
dist2[newx][newy]=dist2[x][y]+1;
rear2++;
}
else if( vis[newx][newy] == 1 )
{
dist2[newx][newy]=dist2[x][y]+1;
printf("To get from %c%d to %c%d takes %d knight moves.\n",sx+'a',sy+1,tx+'a',ty+1,dist1[newx][newy]+dist2[newx][newy]);
ok=1;
break;
}
}
}
front2++;

if(ok)
break;
}

}
}
int main()
{
char ch[10];
while(gets(ch))
{
sx=ch[0]-'a';
sy=ch[1]-'1';
tx=ch[3]-'a';
ty=ch[4]-'1';
memset(vis,0,sizeof(vis));
bfs();
}
return 0;
}



posted on 2011-07-22 19:45  sysu_mjc  阅读(122)  评论(0编辑  收藏  举报

导航