解题报告 Climbing (poj 3328)

2.climbingclimbing.pas/c/cpp

描述:

  Dsqwwe很喜欢旅游,这次他和他的朋友去爬山,途中遇到一处悬崖,dsqwwe决定挑战自己。这处悬崖可以描述为一个n*m的矩阵,矩阵中s代表落脚点,t代表终点,数字带表一只脚落到上面所需时间,X代表此处无法落脚。攀登时,先把左脚或右脚放在任意一处s处,然后另一只脚开始攀登,攀登时,当然是左脚一步,右脚一步。

  若一只脚在(x1,y1),另一只脚落地的范围要保证 |x1-x2|+|y1-y2|<=3,若左脚固定,迈右脚只能往右边迈。右脚固定迈左脚只能向左边迈,如图:

 

当任意一只脚落在t处,则攀登结束,为攀登所需的最少时间为多少

输入(climbing.in)

注意多组数据

对于每组数据,第一行为两个整数,n,m(0<=n,m<=100)

然后就是一个n*m的矩阵,描述悬崖

输出(climbing.out)

若无法完成攀登,输出-1

若可以完成攀登,输出最小时间

样例输入:

6 6

4 4 X X T T

4 7 8 2 X 7

3 X X X 1 8

1 2 X X X 6

1 1 2 4 4 7

S S 2 3 X X

10 2

T 1

1 X

1 X

1 X

1 1

1 X

1 X

1 1

1 X

S S

10 2

T X

1 X

1 X

1 X

1 1

1 X

1 X

1 1

1 X

S S

10 10

T T T T T T T T T T

X 2 X X X X X 3 4 X

9 8 9 X X X 2 9 X 9

7 7 X 7 3 X X 8 9 X

8 9 9 9 6 3 X 5 X 5

8 9 9 9 6 X X 5 X 5

8 6 5 4 6 8 X 5 X 5

8 9 3 9 6 8 X 5 X 5

8 3 9 9 6 X X X 5 X

S S S S S S S S S S

7 10

2 3 2 3 2 3 2 3 T T

1 2 3 2 3 2 3 2 3 2

3 2 3 2 3 2 3 2 3 4

3 2 3 2 3 2 3 2 3 5

3 2 3 1 3 2 3 2 3 5

2 2 3 2 4 2 3 2 3 5

S S 2 3 2 1 2 3 2 3

 

样例输出:

 

12

5

-1

22

12

样例解释

  第一组(l代表左脚,r代表右脚)

4 4 X X T T

4 7 8 2 X 7

3 X X X 1 8

1 R X X X 6

1 1 2 4 4 7

L S 2 3 X X

 

4 4 X X T T

L 7 8 2 X 7

3 X X X 1 8

1 R X X X 6

1 1 2 4 4 7

S S 2 3 X X

 

4 4 X X T T

L 7 8 R X 7

3 X X X 1 8

1 2 X X X 6

1 1 2 4 4 7

S S 2 3 X X

 

4 L X X T T

4 7 8 R X 7

3 X X X 1 8

1 2 X X X 6

1 1 2 4 4 7

S S 2 3 X X

 

4 L X X R T

4 7 8 2 X 7

3 X X X 1 8

1 2 X X X 6

1 1 2 4 4 7

S S 2 3 X X

 

 

 

巨水的宽搜,当然,可以用二维 SPFA ,但是,杀鸡牛刀了。。。。。。。

不过,读入,小心了。。。。。。。。。

 

还有就是,不要深搜,不然要么超时要么 WA ,原因不明。。。

所以我发现,最短路,宽搜王道。。。

 

//PS 几个月后,猛然发现,原来的代码居然有 bug 。。。。。肿么办?真不想改了,so,对不起一下杯具的 std 。

program dsqwwe;
const
dx1:array[1..9] of longint=(2,1,0,-1,-2,1,0,-1,0);
dy1:array[1..9] of longint=(1,1,1,1,1,2,2,2,3);
dx2:array[1..9] of longint=(2,1,0,-1,-2,1,0,-1,0);
dy2:array[1..9] of longint=(-1,-1,-1,-1,-1,-2,-2,-2,-3);
var
first,dis,d,ed:array[0..500000] of longint;
t,l,next:array[1..500000] of longint;
v1,v2:array[1..1000,1..1000] of longint;
map:array[1..1000,1..1000] of boolean;
v:array[1..500000] of boolean;
m,n,i,j,o,closed,open,x,xx,yy,tt,ans,p,c,k:longint;
ss,s:string;
function min(a,b:longint):longint;
begin
if a<b then exit(a)
else exit(b);
end;
procedure add(a,b,c:longint);
begin
inc(o);
t[o]:=b;
l[o]:=c;
next[o]:=first[a];
first[a]:=o;
end;
begin
assign(input,'climbing.in');
reset(input);
assign(output,'climbing.out');
rewrite(output);


while not eof do
begin
readln(m,n);

if n=0 then break;
for i:=1 to n do
for j:=1 to m do
begin
inc(o);
v1[i,j]:=o;
v2[i,j]:=n*m+o;
end;
closed:=0; open:=0; fillchar(d,sizeof(d),0);
fillchar(first,sizeof(first),0); o:=0;
fillchar(map,sizeof(map),false);
fillchar(ed,sizeof(ed),0);
for i:=1 to n do
begin
readln(s);
s:=s+' ';
for j:=1 to m do
begin
p:=pos(' ',s);
ss:=copy(s,1,p-1);
if ss='X' then begin
map[i,j]:=true;
delete(s,1,p);
continue;
end;
if ss='S' then
begin
inc(open);
d[open]:=v1[i,j];
inc(open);
d[open]:=v2[i,j];
c:=0
end
else if ss='T' then
begin
inc(ed[0]);
ed[ed[0]]:=v1[i,j];
inc(ed[0]);
ed[ed[0]]:=v2[i,j];
c:=0;
end
else val(ss,c);
for k:=1 to 9 do
begin
xx:=i+dx1[k];
yy:=j+dy1[k];
if (xx>0) and (xx<=n) and (yy>0) and (yy<=m) and (not map[xx,yy]) then
add(v1[i,j],v2[xx,yy],c);
xx:=i+dx2[k];
yy:=j+dy2[k];
if (xx>0) and (xx<=n) and (yy>0) and (yy<=m) and (not map[xx,yy]) then
add(v2[i,j],v1[xx,yy],c);
end;
delete(s,1,p);
end;
end;
fillchar(v,sizeof(v),false);
filldword(dis,sizeof(dis)>>2,999999);
for i:=1 to open do
begin
v[d[i]]:=true;
dis[d[i]]:=0;
end;
while closed<>open do
begin
inc(closed);
if closed>2*m*n then closed:=1;
x:=d[closed];
p:=first[x];
while p<>0 do
begin
tt:=t[p];
if dis[tt]>dis[x]+l[p] then
begin
dis[tt]:=dis[x]+l[p];
if not v[tt] then
begin
v[tt]:=true;
inc(open);
if open>2*m*n then open:=1;
d[open]:=tt;
end;
end;
p:=next[p];
end;
v[x]:=false;
end;
ans:=maxlongint;
for i:=1 to ed[0] do
ans:=min(ans,dis[ed[i]]);
if ans=999999 then writeln(-1)
else writeln(ans);
end;

close(input);
close(output);
end.

原文地址:https://www.cnblogs.com/SueMiller/p/2237115.html