您的位置:首页 > 其它

POJ 1915 Knight Moves 骑士遍历问题(跳马问题)

2014-07-17 10:21 531 查看
题目来源:http://poj.org/problem?id=1915

1、对于这道题,我首先根据宽度优先搜索的思想,自己独立写出代码。

#include<stdio.h>
int main()
{
short l,n,x,y,x1,y1,k=0,x0,y0;
int i,j,d,e;
short c[301][301],a[90000][2];
short bo;
scanf("%d",&n);
while (n--)
{
k=0;
scanf("%d",&l);
scanf("%d%d%d%d",&x,&y,&x1,&y1);
if ((x==x1)&&(y==y1)) printf("%d\n",k);
else
{
x0=x;y0=y;
a[0][0]=x;a[0][1]=y;
for (i=0;i<l;i++)
for (j=0;j<l;j++)
c[i][j]=0;
i=0;d=0;e=-1;bo=1;
while (bo)
{
k++;
d=e+1;e=i;
for (j=d;j<=e;j++)
{
x=a[j][0]+1;y=a[j][1]+2;
if (x==x1&&y==y1)
{
bo=0;
break;
}
else if ((!c[x][y]&&x>=0&&x<l&&y>=0&&y<l)&&(x>x0-4||x>x1-4)&&(x<x0+4||x<x1+4)&&(y>y0-4||y>y1-4)&&(y<y0+4||y<y1+4))
{
i++;
a[i][0]=x;
a[i][1]=y;
c[x][y]=1;
}
x=a[j][0]+1;y=a[j][1]-2;
if (x==x1&&y==y1)
{
bo=0;
break;
}
else if ((!c[x][y]&&x>=0&&x<l&&y>=0&&y<l)&&(x>x0-4||x>x1-4)&&(x<x0+4||x<x1+4)&&(y>y0-4||y>y1-4)&&(y<y0+4||y<y1+4))
{
i++;
a[i][0]=x;
a[i][1]=y;
c[x][y]=1;
}
x=a[j][0]+2;y=a[j][1]+1;
if (x==x1&&y==y1)
{
bo=0;
break;
}
else if ((!c[x][y]&&x>=0&&x<l&&y>=0&&y<l)&&(x>x0-4||x>x1-4)&&(x<x0+4||x<x1+4)&&(y>y0-4||y>y1-4)&&(y<y0+4||y<y1+4))
{
i++;
a[i][0]=x;
a[i][1]=y;
c[x][y]=1;
}
x=a[j][0]+2;y=a[j][1]-1;
if (x==x1&&y==y1)
{
bo=0;
break;
}
else if ((!c[x][y]&&x>=0&&x<l&&y>=0&&y<l)&&(x>x0-4||x>x1-4)&&(x<x0+4||x<x1+4)&&(y>y0-4||y>y1-4)&&(y<y0+4||y<y1+4))
{
i++;
a[i][0]=x;
a[i][1]=y;
c[x][y]=1;
}
x=a[j][0]-2;y=a[j][1]+1;
if (x==x1&&y==y1)
{
bo=0;
break;
}
else if ((!c[x][y]&&x>=0&&x<l&&y>=0&&y<l)&&(x>x0-4||x>x1-4)&&(x<x0+4||x<x1+4)&&(y>y0-4||y>y1-4)&&(y<y0+4||y<y1+4))
{
i++;
a[i][0]=x;
a[i][1]=y;c[x][y]=1;
}
x=a[j][0]-2;y=a[j][1]-1;
if (x==x1&&y==y1)
{
bo=0;
break;
}
else if ((!c[x][y]&&x>=0&&x<l&&y>=0&&y<l)&&(x>x0-4||x>x1-4)&&(x<x0+4||x<x1+4)&&(y>y0-4||y>y1-4)&&(y<y0+4||y<y1+4))
{
i++;
a[i][0]=x;
a[i][1]=y;c[x][y]=1;
}
x=a[j][0]-1;y=a[j][1]+2;
if (x==x1&&y==y1)
{
bo=0;
break;
}
else if ((!c[x][y]&&x>=0&&x<l&&y>=0&&y<l)&&(x>x0-4||x>x1-4)&&(x<x0+4||x<x1+4)&&(y>y0-4||y>y1-4)&&(y<y0+4||y<y1+4))
{
i++;
a[i][0]=x;
a[i][1]=y;c[x][y]=1;
}
x=a[j][0]-1;y=a[j][1]-2;
if (x==x1&&y==y1)
{
bo=0;
break;
}
else if ((!c[x][y]&&x>=0&&x<l&&y>=0&&y<l)&&(x>x0-4||x>x1-4)&&(x<x0+4||x<x1+4)&&(y>y0-4||y>y1-4)&&(y<y0+4||y<y1+4))
{
i++;
a[i][0]=x;
a[i][1]=y;c[x][y]=1;
}
}
}
printf("%d\n",k);
}
}
return 0;
}


2、我参考题解,给出了优化,把8个“if“语句用一个循环代替,然后优化了初始化步骤。

#include<stdio.h>
int main()
{
short l,n,x,y,x1,y1,k=0,x0,y0,x2,y2;
int i,j,d,e,ii;
short c[300][300],a[90000][2];
short bo;
short dx[8]={1,1,2,2,-1,-1,-2,-2},dy[8]={2,-2,1,-1,2,-2,1,-1};
scanf("%d",&n);
while (n--)
{
k=0;
scanf("%d",&l);
scanf("%d%d%d%d",&x,&y,&x1,&y1);
if ((x==x1)&&(y==y1)) printf("%d\n",k);
else
{
x0=x;y0=y;
a[0][0]=x;a[0][1]=y;
if (x0<=x1) x2=x1;
else {x2=x0;x0=x1;}
if (y0<=y1) y2=y1;
else {y2=y0;y0=y1;}
if (x0-2>=0) x0=x0-2;else x0=0;
if (y0-2>=0) y0=y0-2;else y0=0;
if (x2+2<=l) x2=x2+2;else x2=l-1;
if (y2+2<=l) y2=y2+2;else y2=l-1;
for (i=x0;i<=x2;i++)
for (j=y0;j<=y2;j++)
c[i][j]=0;
i=0;d=0;e=-1;bo=1;
while (bo)
{
k++;
d=e+1;e=i;
for (j=d;j<=e;j++)
{
for (ii=0;ii<8;ii++)
{
x=a[j][0]+dx[ii];
y=a[j][1]+dy[ii];
if (x==x1&&y==y1)
{
bo=0;
j=e+1;
break;
}
else if (!c[x][y]&&x>=x0&&x<=x2&&y>=y0&&y<=y2)
{
i++;
a[i][0]=x;
a[i][1]=y;
c[x][y]=1;
}
}
}
}
printf("%d\n",k);
}
}
return 0;
}

3、运用队列的bfs

#include <iostream>
#include <queue>
using namespace std;
int xf,yf,xl,yl,n,dis[300][300],map[300][300];
int dx[8]={1,1,-1,-1,2,2,-2,-2};
int dy[8]={2,-2,2,-2,1,-1,1,-1};
void bfs()
{
int vx,vy,tx,ty,i,bo=1;
queue <int>q;
memset(map,0,sizeof(map));
memset(dis,0,sizeof(dis));
dis[xf][yf]=1;
q.push(xf);
q.push(yf);
while((!q.empty())&&bo)
{
vx=q.front();q.pop();
vy=q.front();q.pop();
for(i=0;i<8;i++)
{
tx=vx+dx[i];
ty=vy+dy[i];
if(tx==xl && ty==yl)
{
bo=0;
map[tx][ty]=map[vx][vy]+1;
break;
}
else if(!dis[tx][ty] && tx<n && tx>=0 && ty>=0 && ty<n)
{
q.push(tx);
q.push(ty);
dis[tx][ty]=1;
map[tx][ty]=map[vx][vy]+1;
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
scanf("%d%d%d%d",&xf,&yf,&xl,&yl);
map[xl][yl]=0;
if(xf==xl && yf==yl) printf("%d\n",map[xl][yl]);
else
{
bfs();
printf("%d\n",map[xl][yl]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  遍历 poj 搜索 bfs