因为是8×8的方格,所以枚举终点位以及亚瑟王与骑士相遇的相遇位,floyd求一下最短路,最后去一下那个遇到亚瑟王的骑士的重复步数。
恩……刚开始没有思路……用DP没有做出来……(╯﹏╰)然后看了其他用枚举的思路……(づ。◕‿‿◕。)づ
我会好好记住的!!
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int kmove[8][2]={{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
int knmove[8][2]={{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}};
const int inf=100000000;
int kmap[64][64];
int knmap[64][64];
int i,j;
bool ok(int x,int y) //判断位置的正确性
{
if(x>=0&&x<8&&y>=0&&y<8) return true;
else return false;
}
void getxy(int p,int &x,int &y) //得出坐标
{
x=p%8;
y=p/8;
}
int getPosition(int x,int y) //得出数字位置
{
return x+y*8;
}
void init() //初始化
{
for(int i=0;i<64;++i)
{
for(int j=0;j<64;++j)
{kmap[i][j]=inf;knmap[i][j]=inf;}
kmap[i][i]=0;
knmap[i][i]=0;
int x,y,tx,ty;
int next;
getxy(i,x,y);
for(j=0;j<8;++j)
{
tx=kmove[j][0]+x;
ty=kmove[j][1]+y;
if(ok(tx,ty))
{
next=getPosition(tx,ty);
kmap[i][next]=1;
}
tx=knmove[j][0]+x;
ty=knmove[j][1]+y;
if(ok(tx,ty))
{
next=getPosition(tx,ty);
knmap[i][next]=1;
}
}
}
}
void floyd() //最短路
{
for(int k=0;k<64;++k)
for(int i=0;i<64;++i)
for(int j=0;j<64;++j)
{
kmap[i][j]=kmap[i][j]<(kmap[i][k]+kmap[k][j])?kmap[i][j]:(kmap[i][k]+kmap[k][j]);
knmap[i][j]=knmap[i][j]<(knmap[i][k]+knmap[k][j])?knmap[i][j]:(knmap[i][k]+knmap[k][j]);
}
}
int main()
{
string s;
int num,size,minmove,sum;
int position[64];
init();
floyd();
cin>>s;
size=s.size();
num=0;
for(int i=0;i<size;i+=2)
position[num++]=s[i]-'A'+(s[i+1]-'1')*8;
minmove=inf;
for(int ds=0;ds<64;++ds) //最终位
for(int m=0;m<64;++m) //相遇位
for(int k=1;k<num;++k) //相遇骑士
{
sum=0;
for(int i=1;i<num;++i) sum+=knmap[position[i]][ds];//骑士到达终点位步数
sum+=kmap[position[0]][m]; //国王到相遇位步数
sum+=knmap[position[k]][m]+knmap[m][ds]; //骑士k于相遇位到最终位的步数
sum-=knmap[position[k]][ds]; //减去k骑士多算的一次
if(sum<minmove) minmove=sum;
}
printf("%d\n",minmove);
return 0;
}