实在看不下去了,楼上的题解是个啥ID34354的题解还没有注释…
算了…
盯着看了2个小时,算是看懂了,解释一下吧
顺便给P党一些福音QAQ
为了解释方便,变量名几乎没变QAQ
const z:array[1..4,1..2]of -1..1=((0,1),(1,0),(0,-1),(-1,0));//常量数组
//这个不可以随便定义
{
要→↓←↑的方式定义,不然...
}
var i,j,k,m,n,p,q,x,y,v,o:longint;
a:array[0..1001,0..1001]of char;
procedure dfs(x,y:longint);//该程序最玄学的部分
var i,c,p,v:longint;
u:array[1..4]of longint;
begin
c:=0;
for i:=1 to 4 do
if a[x+z[i,1],y+z[i,2]]='A' then//统计出周围的A的个数与方向
begin
inc(c);
u[c]:=i;
end;
if(c=2)and
((u[1]=1)and(u[2]=3)
or(u[1]=2)and(u[2]=4)or
(a[x-z[u[1],1]-z[u[2],1],
y-z[u[1],2]-z[u[2],2]]='x'))then
exit;
{(Y为现在查找的位置)
当出现
A
Y
A
或
AYA
这种情况则可能是通道,不可以删去
还有一种情况
A
AY
x
这个情况比较特殊,因为不可以从x的外面走,所以Y是通道,不能删去
}
if(c>1)then
begin
a[x,y]:='A';
//把当前位置删去
for i:=1 to 4 do
begin
p:=x+z[i,1];
v:=y+z[i,2];
if(p>1)and(v>1)and(p<n)and(v<m)and(a[p][v]='.') then
dfs(p,v);//查找下一个位置
end;
end;
end;
function vaild(x,y:longint):boolean;//判断这格可不可以走
begin
exit((x>0)and(y>0)and(x<n+1)and(y<m+1)and(a[x,y]='.'));
end;
function left(fx:longint):longint;//左转
begin
if fx=1 then exit(4) else exit(fx-1);
end;
function right(fx:longint):longint;//右转
begin
if fx=4 then exit(1) else exit(fx+1);
end;
begin
readln(n,m);
for i:=1 to n do
begin
for j:=1 to m do
read(a[i,j]);
readln;
end;
for i:=2 to n-1 do
for j:=2 to m-1 do
if a[i,j]='.' then
dfs(i,j);
{看一下DFS完成后的样例效果
把没用的.都变成了A
...................
...................
....AAA............
....AAA.x..........
..x.AAA...AAAAA....
....AAAAAAAAAAA....
....AAAAAAAAAAA....
....AAAAAAA...A....
.xx.AAAAAAA.x.A....
....AAAAAAA........
...AAAAAAAAAAAAA...
...................
}
o:=0;//储存答案
for i:=1 to n do
for j:=1 to m do
if a[i,j]='A' then
begin
//可以得出,该最佳路线必然进过最上端的A的上面
p:=i-1;
q:=j;
v:=1;
repeat//这个可以说是贪心吧...
{
为了让改路线尽可能的贴着大陆走
语文初始方向为→
所以说要贴着走的话,当可以右转时要右转,不可以则尽可能直走,再不行就只能左转,这样还可以防止直接走回起点(终点)
就是要绕着这个处理好的岛屿顺时针转一圈
}
if(vaild(p+z[right(v),1],q+z[right(v),2]))then//最好右转
begin
p:=p+z[right(v),1];
q:=q+z[right(v),2];
v:=right(v);
end
else
if(vaild(p+z[v,1],q+z[v,2]))then//尽可能直走
begin
p:=p+z[v,1];
q:=q+z[v,2];
end
else
if(vaild(p+z[left(v),1],q+z[left(v),2]))then//实在不行就左转
begin
p:=p+z[left(v),1];
q:=q+z[left(v),2];
v:=left(v);
end;
inc(o);//每走一步答案+1
until(p=i-1)and(q=j);//转了一圈就结束了
write(o);//输出结果
{(+为走过的路线,F为起点)最后效果就是这样
...................
...+F+++...........
...+AAA+...........
...+AAA+x+++++++...
..x+AAA+++AAAAA+...
...+AAAAAAAAAAA+...
...+AAAAAAAAAAA+...
...+AAAAAAA+++A+...
.xx+AAAAAAA+x+A+...
..++AAAAAAA++++++..
..+AAAAAAAAAAAAA+..
..+++++++++++++++..
}
exit;
end;
end.
只能说,有题解是好事,没有解释怎么办呢…QAQ