骑士聚会问题:
    在一个N*N的棋盘上放m个马,问各自跳多少步才能在某处聚在一起(马跳日),要求聚会时间越早越好,并且总步数要最少。并在满足上述条件下,求出每个骑士到达聚会点的跳步路线。
思路:
    首先每一个骑士都从各自的起点开始跳,分别从八个方向来判断下一步要跳到的位置,循环每一个可能,并将棋盘跳满,并标记该骑士从起点跳到棋盘上每位置的步数。
    其次搜索棋盘上每一位置,所有骑士跳到该位置的最大步数(也就是从开始跳到聚会开始的时间间隔天数)--这个数要求最小,并计算所有骑士跳到该位置的总步数
    再次根据每个位置上最大步数最小的那个就是所求的聚会点
    接下来,根据聚会点,分别求出每个骑士到达该聚会点的跳步方式,这个就有点像八皇后问题了,根据起点,聚会点,跳步数来递归求出每个骑士(满足题目要求时间最早,总步数最少)来参加聚会的跳步路线
 
#include "stdio.h"
#include "windows.h"
#define MAXX 5
#define MAXY 5
#define NUM_QISHI 4//number of qishi
struct Point
{
 int x;
 int y;
}Quene[MAXX*MAXY],StartPoint[NUM_QISHI],PartyPoint;
struct Point PathPoint[MAXX];//record the points of qishi get to partypoint
int nStates[NUM_QISHI][MAXX][MAXY];//the steps when qishi get to the point
int dx[8] = {1,2,2,1,-1,-2,-2,-1};
int dy[8] = {-2,-1,1,2,2,1,-1,-2};
void Init()
{
 int i = 0;
 int x1 = 0;
 int y1 = 0;
 //the startpoint of the first qishi
 StartPoint[0].x = 0;
 StartPoint[0].y = 0;
 StartPoint[1].x = 1;
 StartPoint[1].y = 4;
   
 StartPoint[2].x = 1;
 StartPoint[2].y = 2;
 StartPoint[3].x = 3;
 StartPoint[3].y = 4;
 memset(Quene,0,sizeof(Quene));
 memset(nStates,-1,sizeof(nStates));
 for(i = 0; i < NUM_QISHI; i++)
 {
  x1 = StartPoint[i].x;
  y1 = StartPoint[i].y;
  nStates[i][x1][y1] = 0;
 }
}
void QishiFillFullSpace(int nNumber)
{
 int head;
 int tail;
 int step;
 int tX,tY;
 int tTail,tHead;
 int i = 0;
 head = 0;
 tail = 0;
 step = 0;
 Quene[head].x = StartPoint[nNumber].x;
 Quene[head].y = StartPoint[nNumber].y;
 while(head <= tail)
 {
  tTail = tail;
  for(tHead = head; tHead <= tTail; tHead++)
  {
   for(i = 0; i < 8; i++)
   {
    tX = Quene[tHead].x + dx[i];
    tY = Quene[tHead].y + dy[i];
    if((tX >= 0 && tX < MAXX) && (tY >= 0 && tY < MAXY) && nStates[nNumber][tX][tY] == -1)
    {
     tail++;
     Quene[tail].x = tX;
     Quene[tail].y = tY;
     nStates[nNumber][tX][tY] = step + 1;
    }
   }
  }
  head = tTail + 1;
  step++;
 }
}
void SearchPartyPoint()
{
 int i = 0;
 int j = 0;
 int k = 0;
 int sum = 0;
 int mindays = 12345;
 int minx = -1;
 int miny = -1;
 for(i = 0; i < MAXX; i++)
 {
  for(j = 0; j < MAXY; j++)
  {
   int tSum = 0;
   int tMaxdays = 0;
   for(k = 0; k < NUM_QISHI; k++)
   {
    if(nStates[k][i][j] > tMaxdays)
    {
     tMaxdays = nStates[k][i][j];
    }
    tSum = tSum + nStates[k][i][j];
   }
   if(tMaxdays < mindays)
   {
    mindays = tMaxdays;
    sum = tSum;
    minx = i;
    miny = j;
   }
  }
 }
 PartyPoint.x = minx;
 PartyPoint.y = miny;
}
void PrintSolution(int numb)
{
 int i = 0;
 int steps = nStates[numb][PartyPoint.x][PartyPoint.y];
 printf("qishi %d to party solution:\r\n",numb);
 printf("Start point is x = %d, y = %d\r\n",StartPoint[numb].x,StartPoint[numb].y);
 for(i = 0; i < steps; i++)
 {
  printf("%d step is: x = %d, y = %d\r\n",i+1,PathPoint[steps-i-1].x,PathPoint[steps-i-1].y);
 }
 printf("\r\n");
 printf("\r\n");
}
void FindPath(struct Point StartPoint, struct Point EndPoint, int steps, int numb)
{
 int tSteps = 0;
 int i = 0;
 struct Point tPoint;
 tPoint.x = -1;
 tPoint.y = -1;
 if(steps <= 0)
 {
  return;
 }
 for(i = 0; i < 8; i++)
 {
  tPoint.x = StartPoint.x + dx[i];
  tPoint.y = StartPoint.y + dy[i];
  if((tPoint.x >= 0 && tPoint.x < MAXX) && (tPoint.y >= 0 && tPoint.y < MAXY))
  {
   tSteps++;
   PathPoint[steps-1].x = tPoint.x;
   PathPoint[steps-1].y = tPoint.y;
   if(tSteps < steps)
   {
    FindPath(tPoint,EndPoint,steps-1,numb);
   }
   else
   {
    if((tSteps == steps) && (tPoint.x == EndPoint.x) && (tPoint.y == EndPoint.y))
    {
     PrintSolution(numb);
    }
   }
   tSteps--;
   PathPoint[steps-1].x = -1;
   PathPoint[steps-1].y = -1;
  }
 }
}
void main()
{
 int i = 0;
 Init();
 
 for(i = 0; i < NUM_QISHI; i++)
 {
  QishiFillFullSpace(i);
 }
 SearchPartyPoint();
 printf("The party point is x = %d, y = %d\r\n",PartyPoint.x,PartyPoint.y);
 printf("\r\n");
 for(i = 0; i < NUM_QISHI; i++)
 {
  FindPath(StartPoint[i],PartyPoint,nStates[i][PartyPoint.x][PartyPoint.y],i);
 }
}