参考:
http://blog.csdn.net/lijiecsu/article/details/7579855
使用枚举法
如果确定了最终的位置、国王和骑士相遇的位置、国王与哪个骑士相遇三个要素,则最少移动步数就确定了。
最终的位置共有64种,国王和骑士相遇的位置也有64种,设有N个骑士,则国王与哪个骑士相遇有N种,则枚举O(64*64*N)
对某个最终位置dst,相遇位置m,遇到国王的骑士k:
1 计算所有骑士到dst的最少移动步数。
2 加上国王移动到m的最少移动步数。
3 加上骑士k经过m到dst的最少移动步数。
4 减去骑士k到dst的最少移动步数。(骑士k在第1步中也算了一遍,所以要减去)
5 如果总的最少步数比当前已经求出的最少步数少,则更新最少步数。
枚举完后输出最后结果。
对于国王和骑士从某一点到另外一点的最少移动步数,采用floyd算法可以求出。
code:写的很乱
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
#define inf (1000000000)
#define MAX_N 64
int kdis[MAX_N][MAX_N];
int nightdis[MAX_N][MAX_N];
struct move
{
int x;
int y;
}NIGHTMOVE[]={ {-2,1},{2,1},{-2,-1},{2,-1},{1,2},{-1,2},{1,-2},{-1,-2} };
struct move KMOVE[]= { {-1,1},{0,1},{1,1},{-1,0},{1,0},{-1,-1},{0,-1},{1,-1}};
bool valid(int x,int y)
{
if( x >= 0 && x < 8 && y >= 0 && y < 8)
return true;
return false;
}
int nightfloyd()
{
for(int i=0;i<MAX_N;i++)
for(int j=0;j<MAX_N;j++)
{
nightdis[i][j]=inf;
kdis[i][j]=inf;
if( i == j)
{
nightdis[i][j]=0;
kdis[i][j]=0;
}
}
for(int i=0;i<MAX_N;i++)
{
int x = i %8;
int y = i/8;
for(int m=0;m< 8;m++)
{
int mx = x + NIGHTMOVE[m].x;
int my = y + NIGHTMOVE[m].y;
int kmx = x + KMOVE[m].x;
int kmy = y + KMOVE[m].y;
if(valid(mx,my))
{
int j=( my * 8 + mx);
nightdis[i][j] = 1;
}
if(valid(kmx,kmy))
{
int j = (kmy *8) + kmx;
kdis[i][j] = 1;
}
}
}
for(int k=0;k<MAX_N;k++)
{
for(int i=0;i<MAX_N;i++)
{
for(int j=0;j<MAX_N;j++)
{
kdis[i][j] = min(kdis[i][k]+kdis[k][j],kdis[i][j]);
nightdis[i][j] = min(nightdis[i][k]+nightdis[k][j],nightdis[i][j]);
//printf("********nightdir[%d][%d]=%d\n",i,j,nightdis[i][j]);
}
}
}
for(int i=0;i<64;i++)
{
for(int j=0;j<64;j++)
{
//printf("king[%d][%d]=%d\n",i,j,kdis[i][j]);
//printf("kight[%d][%d]=%d\n",i,j,nightdis[i][j]);
}
}
}
int K=0;
int I[MAX_N]; //I[0]表示国王的起点位置
int get_index(char c,char n)
{
//I[0] = (str[0] - 'A') + ( str[1] -1)*8;
return (c - 'A') + ( n -'1') *8;
}
int knight_sum_but_k(int k,int f) //除了k,其它所有骑士到终点f的最短距离之和
{
int sum = 0;
for(int i=1;i<=K;i++)
{
if( i==k)
continue;
sum += nightdis[I[i] ][f];
}
//printf("knight_sum_but_k k=%d,f=%d,sum=%d\n",k,f,sum);
return sum;
}
int king_to(int king,int f)
{
return kdis[king][f];
}
int knight_to(int night,int f)
{
return nightdis[night][f];
}
int main()
{
string str;
nightfloyd();
while(cin>>str)
{
int minret = inf;
int L=str.length();
I[0] = get_index(str[0],str[1]);
for(int l=2;l<L;l += 2)
{
K++;
I[K] = get_index(str[l],str[l+1]);
}
//printf("K=%d\n",K);
for(int i=0;i<64;i++)
{
for(int j=0;j<64;j++)
{
for(int k=1;k<=K;k++)
{
//最终i,国王与k相遇在j
int sum = 0;
sum += knight_sum_but_k(k,i);
sum += king_to(I[0],j);
sum += knight_to(I[k],j);
sum += knight_to(j,i);
if(sum < minret)
minret = sum;
//printf("i=%d,j=%d,k=%d,sum=%d\n",i,j,k,sum);
}
}
}
cout<<minret<<endl;
}
}