这题主要是玄学输入+玄学理解+玄学时间复杂度+玄学定理呀QAQ…
至于玄学理解其他题解已经讲得很清楚了呀,主要还是让大家看看我的玄学代码呀QAQ…
//先玄学理解呀
const z:array[1..8,1..2]of -2..2=((1,2),(1,-2),(-1,2),(-1,-2),(2,1),(2,-1),(-2,1),(-2,-1));
var i,j,k,ix,iy:longint;
m,n,h,t,sum,q:longint;
kingx,kingy:longint;
x_ch:array[char]of longint;
min,p:array[-1..100,-1..100]of longint;
x,y,u:array[0..10000]of longint;
main:longint=maxlongint;
boo:array[-1..100,-1..100]of boolean;
ans:array[-1..30,-1..50,-1..30,-1..50] of longint;
s:string;
ch:char;
function mine(m,n:longint):longint;//min
begin
if m>n then exit(n) else exit(m);
end;
function max(m,n:longint):longint;//max
begin
if m>n then exit(m) else exit(n);
end;
procedure find(x1,y1:longint);//以x1,y1为终点呀QAQ
var i,j,k,pd:longint;
begin
for i:=-2 to 2 do//玄学定理,不知道是谁怎么的呀
for j:=-2 to 2 do//接国王的位置一定在国王旁边2格内
if boo[kingx+i,kingy+j] then
begin
pd:=0;
for k:=1 to sum do
inc(pd,ans[x1,y1,x[k],y[k]]);
main:=mine(main,pd+max(abs(x1-kingx),abs(y1-kingy)));//当国王直接走到终点
for k:=1 to sum do
begin
main:=mine(main,
pd-ans[x1,y1,x[k],y[k]]{骑士直接去终点}+ans[kingx+i,kingy+j,x[k],y[k]]{骑士到接的位置}+
ans[x1,y1,kingx+i,kingy+j]{从接的位置到终点}+max(abs(i),abs(j))){国王到接的位置};//第k个骑士去接国王呀
end;
end;
end;
begin
readln(m,n);
k:=m;
m:=n;
n:=k;
for ch:='A' to 'Z' do x_ch[ch]:=ord(ch)-ord('A')+1;
read(ch,k);kingx:=x_ch[ch];kingy:=k;//读入国王位置呀QAQ
for ix:=1 to m do
for iy:=1 to n do
for i:=1 to m do
for j:=1 to n do ans[ix,iy,i,j]:=123123123;//赋初值
for ix:=1 to m do//用bfs计算每两个点之间的最短步数,四次居然不超呀,玄学时间复杂度....
for iy:=1 to n do
begin
x[1]:=ix;
y[1]:=iy;
u[1]:=0;
h:=1;
t:=1;
for i:=1 to m do
for j:=1 to n do
boo[i,j]:=true;
boo[ix,iy]:=false;
ans[ix,iy,ix,iy]:=0;
repeat
for i:=1 to 8 do
if boo[x[t]+z[i,1],y[t]+z[i,2]] then
begin
inc(h);
x[h]:=x[t]+z[i,1];
y[h]:=y[t]+z[i,2];
u[h]:=u[t]+1;
ans[ix,iy,x[h],y[h]]:=u[h];//保存最优解呀
boo[x[h],y[h]]:=false;
end;
inc(t);
until t>h;
end;
while not eof do//玄学读入
begin
readln(s);//字符串,真麻烦...
for i:=1 to length(s) do
begin
if (s[i] in ['A'..'Z']) then
begin
inc(sum);
x[sum]:=x_ch[s[i]];
k:=0;
j:=i+2;
while (s[j] in ['0'..'9']) and (j<=length(s))do
begin
k:=k*10+ord(s[j])-48;
inc(j);
end;
y[sum]:=k;
end;
end;
end;
if sum=0 then begin write(0); exit; end;
for i:=1 to m do
for j:=1 to n do boo[i,j]:=true;
for i:=1 to m do
for j:=1 to n do
begin
find(i,j);//找最优解呀QAQ
end;
write(main);//输出
end.
这是一道玄学难题,难度挺高的,辛苦调了2个小时,,,