第一眼看过去,就知道,一定是搜索,什么**大哥**什么**二哥**什么。。。。。**小明**?实际上呢,题目有点像脑筋急转弯,好好玩哎,小明的妈妈有三个孩子,大哥叫大明,二哥叫二明,三弟叫——**小X**噗哈哈哈哈,等等,跑题了额,(尴尬),咳咳,切入正题,数据是
数据范围限制
其中,T < 200,3 <= n, m <= 100,0 <= t <= 100。
所以,深搜还真的不一定行,这时候,宽搜就出来了。
首先,我们将大哥和二哥的坐标向四周扩散,然后,判断能不能标记,能就标记,不能就不标记,并退出,说了这么久,还是来说说宽搜吧。贡献个代码!
const fx:array[1..4,1..2]of longint=((0,1),
(1,0),
(-1,0),
(0,-1));
var
n,m,mm,t,i,j,h,sum,x,y,l,r,tt,xxxx,k,o,p,oo,pp,g,ii,ans:longint;
d:array[0..100000,0..3]of longint;
a:array[0..1000,0..1000]of char;
bz1:boolean;
bz,bz2:array[1..1000,1..1000,0..3]of boolean;
s:string;
begin
assign(input,'seek.in');
reset(input);
assign(output,'seek.out');
rewrite(output);
readln(n);
for i:=1 to n do
begin
readln(m,mm,tt);
fillchar(a,sizeof(a),0);
l:=0;
fillchar(bz,sizeof(bz),false);
fillchar(bz2,sizeof(bz2),false);//初始化
for j:=1 to m do
begin
for k:=1 to mm do
begin
read(a[j,k]);
if(a[j,k]='D')then
begin
o:=j;
p:=k;
end;
if(a[j,k]='E')then
begin
oo:=j;
pp:=k;//记录大哥二哥的位置
end;
if(a[j,k]='S')then
begin
a[j,k]:='.';
d[1,1]:=j;
d[1,2]:=k;
d[1,3]:=0;//小X的位置
end;
end;
readln;
end;
for k:=1 to 4 do
begin
x:=fx[k,1]+o;
y:=fx[k,2]+p;
while a[x,y]='.' do
begin
bz[x,y,1]:=true;
x:=x+fx[k,1];
y:=y+fx[k,2];//标记四周,向四周扩散标记
end;
end;
for k:=1 to 4 do
begin
x:=fx[k,1]+oo;
y:=fx[k,2]+pp;
while a[x,y]='.' do
begin
bz[x,y,2]:=true;
x:=x+fx[k,1];
y:=y+fx[k,2];//同上
end;
end;
for j:=1 to 2 do
begin
if bz[d[1,1],d[1,2],j] then
begin
inc(d[1,3],j);//判断是否可以直接看到他们
end;
end;
if d[1,3]=3 then
begin
writeln('Case ',i,':');
writeln(0);
continue;
end;
h:=1;
t:=1;
sum:=0;
bz1:=false;
ans:=0;
g:=0;
while(h<=t)and(ans<tt)do
begin
g:=t+1;
inc(ans);
for ii:=h to t do//队列中的每一个位置都去枚举
begin
for j:=1 to 4 do
begin
x:=d[ii,1]+fx[j,1];
y:=d[ii,2]+fx[j,2];
if(x>=1)and(x<=m)and(y>0)and(y<=mm)and(a[x,y]='.')then//判断范围
begin
sum:=d[ii,3];
if(bz[x,y,1])and(sum<>1)then
begin
inc(sum);
end;
if(bz[x,y,2])and(sum<2)then//判断能否看到大哥二哥
begin
inc(sum,2);
end;
if(sum=3)then
begin
bz1:=true;
break;
end;
if(bz2[x,y,sum]=false)then
begin
bz2[x,y,sum]:=true;
inc(t);
d[t,1]:=x;
d[t,2]:=y;
d[t,3]:=sum;//加入队列
end;
end;
end;
if(bz1)then break;
end;
if(bz1)then break;
h:=g;
end;
if(bz1)then
begin
writeln('Case ',i,':');
writeln(ans);//输出
end
else
begin
writeln('Case ',i,':');
writeln('-1');
end;
end;
end.
这样,就可以对了,代码有点长,最近人品不好,十滴水打了一万多byte都错了,这题一开始也是一万多byte,后来才改的,呜呜呜