在8×8的棋盘上分布着n个骑士,他们想约在某一格的中聚会,骑士每天可以像国际象棋中的马那样移动一次,如下图所示,可以从中间向8个方向移动,请你计算n个骑士的最早聚会地点和要走多少天。要求尽早聚会,且n个人走的总步数最少,先到聚会地点的骑士可以不再移动等候其他骑士。
从键盘输入n(0<n<=64),然后依此输入n个骑士的初始位置xi,yi(0<=xi,yi<=7)。屏幕输出以空格分隔的三个整数,分别为聚会点的x,y值,以及要走多少天。
#include<iostream>
using namespace std;
int pos[9][9];
int day[9][9];
int a[2][8]={{1,-1,1,-1,2,-2,2,-2},{2,2,-2,-2,1,1,-1,-1}};
typedef struct tagNode
{
int x;
int y;
struct tagNode *next;
}Node;
typedef struct tagSeq
{
Node *front;
Node *rear;
}Seq;
void qishi(int x,int y)
{
Seq lq;
Node *p,*q;
int i,count=0,re,rea=0;
lq.front=lq.rear=(Node *)malloc(sizeof(Node));
lq.front->next=lq.rear->next=NULL;
p=(Node *)malloc(sizeof(Node));
p->x=x;
p->y=y;
lq.rear->next=p;
lq.rear=p;
pos[x][y]=1;
re=1;
while(lq.front!=lq.rear)
{
while(re)//判断位于同一级别的元素是否出队完毕
{
re–;
q=lq.front;
lq.front=lq.front->next;
free(q);
if(count>day[lq.front->x][lq.front->y])
day[lq.front->x][lq.front->y]=count;
for(i=0;i<=7;i++)
{
if(a[0][i]+lq.front->x>=0&&a[0][i]+lq.front->x<=8&&
a[1][i]+lq.front->y>=0&&a[1][i]+lq.front->y<=8&&pos[a[0][i]+lq.front->x][a[1][i]+lq.front->y]==0)
{
p=(Node *)malloc(sizeof(Node));
p->x=lq.front->x+a[0][i];
p->y=lq.front->y+a[1][i];
lq.rear->next=p;
lq.rear=p;
pos[a[0][i]+lq.front->x][a[1][i]+lq.front->y]=1;
rea++;
}
}
}
re=rea;
rea=0;
count++;
}
}
int main()
{
int x,y,n,i,j,k1,k2;
memset(day,0,sizeof(day));
memset(pos,0,sizeof(pos));
cin>>n;
for(i=1;i<=n;i++)
{
cin>>x>>y;
qishi(x,y);
memset(pos,0,sizeof(pos));
}
int min=day[0][0];
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
if(day[i][j]<min)
{
min=day[i][j];
k1=i;
k2=j;
}
}
}
cout<<min<<endl;//输出最少天数
cout<<k1<<” “<<k2<<endl;//骑士聚会的地点
return 0;
}