# poj2243 Knight Moves 骑士游历问题的纯数学方法！！！

http://poj.org/problem?id=2243

e2 e4

a1 b2

b2 c3

a1 h8

a1 h7

h8 a1

b1 c3

f6 f6

To get from e2 to e4 takes 2 knight moves.

To get from a1 to b2 takes 4 knight moves.

To get from b2 to c3 takes 2 knight moves.

To get from a1 to h8 takes 6 knight moves.

To get from a1 to h7 takes 5 knight moves.

To get from h8 to a1 takes 6 knight moves.

To get from b1 to c3 takes 1 knight moves.

To get from f6 to f6 takes 0 knight moves.

-------------------------------------------------------------------------------------------------------------

a+2b+2c+d=x

2a+b-c-2d=y

c=(-4a-5b+2x+y)/3

d=(5a+4b-x-2y)/3

n*n的稍作修改即可。

--------------------------------

#include <iostream>
#include <string>
using namespace std;

int f(int a)    //就是abs(a)，绝对值
{
if (a<0)
return 0-a;
return a;
}

int main()
{
string s1,s2;
int a,b,c,d,x,y,s,m;
while (cin >> s1 >> s2)
{
if ((s1=="a1" && s2=="b2") || (s1=="b2" && s2=="a1") || (s1=="g2" && s2=="h1") || (s1=="h1" && s2=="g2"))
{
cout << "To get from " << s1 << " to " << s2 << " takes 4 knight moves." << endl;
continue;
}
if ((s1=="a8" && s2=="b7") || (s1=="b7" && s2=="a8") || (s1=="g7" && s2=="h8") || (s1=="h8" && s2=="g7"))
{
cout << "To get from " << s1 << " to " << s2 << " takes 4 knight moves." << endl;
continue;
}
x=s2[0]-s1[0];    //横坐标差值
s=9999;
y=s2[1]-s1[1];    //纵坐标差值
for (b=-4;b<=4;b++)    //对b枚举
{
m=y+2*x-2*b+30;    //a模3的余数
m%=3;
for (a=m-6;a<=m+6;a+=3)     //对a枚举
{
c=(2*x+y-4*a-5*b)/3;    //求出c和d
d=(5*a+4*b-x-2*y)/3;
if (s>f(a)+f(b)+f(c)+f(d))
s=f(a)+f(b)+f(c)+f(d);     //判断是否是最小的
}
}
cout << "To get from " << s1 << " to " << s2 << " takes " << s << " knight moves." << endl;
}
return 0;
}