骑士聚会问题

来源:互联网 发布:非凡软件站安全吗 编辑:程序博客网 时间:2024/05/17 03:39

    在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;
}