问题描述: | 桃花岛其实也没什么好玩的,黄蓉经常偷偷跑到江湖上与洪七公等人玩。于是,黄药师就 经常想一些游戏与女儿玩,为了是把黄蓉留在身边,江湖险恶啊! 比如,黄蓉开始时站在A点,她的家在B点,黄药师连续说了一串: NNNENNWWWSSW,则走了如下一个线路。然后,黄药师会问黄蓉:中间有没有走“弯 路”了?即有没有捷径好走?比如,下图中就有多条捷径,可以从C走NN而到E,或走WW 直接到D。 | |
数据输入: | 第一行是一个整数n( 3 <= n <= 250000)表示黄药师所报出的字符串长度。 | |
结果输出: | 输出只有一行,由3个数字和1个字符组成,中间用1个空格隔开。 | |
样例: | 12 NNNENNWWWSSW | 2 3 11 W |
核心思想: | 双快排,然后比较就好 |
type
atp=record
x,y,num:longint;
end;
var
a:array[-2..250010]of atp;
n,st,ed,t1,t2,ans:longint;
ch:char;
//==============================================================
procedure init;
var
i:longint;
begin
fillchar(a,sizeof(a),0);
readln(n);
fori:=1 to n do
begin
read(ch);
a[i]:=a[i-1];
a[i].num:=i;{<原位置>}
case ch of
'E':inc(a[i].y);{<求(x,y)坐标>}
'W':dec(a[i].y);
'N':inc(a[i].x);
'S':dec(a[i].x);
end;
end;
end;
//==========================================================
procedure qsortx(l,r:longint);
var
i,j:longint;
k,t:atp;
begin
i:=l;j:=r;
k:=a[(l+r)shr 1];
repeat
while (a[i].x<k.x)or((a[i].x=k.x)and(a[i].y<k.y)) do inc(i);
while (a[j].x>k.x)or((a[j].x=k.x)and(a[j].y>k.y)) do dec(j);
ifi<=j then
begin
t:=a[i];a[i]:=a[j];a[j]:=t;
inc(i);dec(j);
end;
until i>j;
ifi<r then qsortx(i,r);
ifj>l then qsortx(l,j);
end;
procedure qsorty(l,r:longint);
var
i,j:longint;
k,t:atp;
begin
i:=l;j:=r;
k:=a[(l+r)shr 1];
repeat
while (a[i].y<k.y)or((a[i].y=k.y)and(a[i].x<k.x)) do inc(i);
while (a[j].y>k.y)or((a[j].y=k.y)and(a[j].x>k.x)) do dec(j);
ifi<=j then
begin
t:=a[i];a[i]:=a[j];a[j]:=t;
inc(i);dec(j);
end;
until i>j;
ifi<r then qsorty(i,r);
ifj>l then qsorty(l,j);
end;
//===========================================================
function pd(x,y,z:longint):boolean;{<按题目要求,先比长度再比开始点,最后比结束点>}
begin
ifx<ans then exit(true);
ifx>ans then exit(false);
ifst>y then exit(true);
ifst<y then exit(false);
ifed<z then exit(true);
exit(false);
end;
//==============================================================
procedure work1;
var
i,j:longint;
ct:char;
begin
fori:=1 to n-1 do
ifa[i].x=a[i+1].x then{<在同一行>}
begin
j:=a[i+1].y-a[i].y;{<列差即为路径长度>}
if a[i].num<a[i+1].num then
begin
t1:=a[i].num;
t2:=a[i+1].num;
ct:='E';
end
else
begin
t1:=a[i+1].num;
t2:=a[i].num;
ct:='W';
end;
if t1+1=t2 then continue;{<若坐标并非按原序相连,则继续否则返回循环>}
if pd(j,t1,t2) then
begin
ans:=j;
st:=t1;
ed:=t2;
ch:=ct;
end;
end;
end;
//=============================================================
procedure work2;
var
i,j:longint;
ct:char;
begin
fori:=1 to n-1 do
ifa[i].y=a[i+1].y then
begin
j:=a[i+1].x-a[i].x;
if a[i].num<a[i+1].num then
begin
t1:=a[i].num;
t2:=a[i+1].num;
ct:='N';
end
else
begin
t1:=a[i+1].num;
t2:=a[i].num;
ct:='S';
end;
if t1+1=t2 then continue;
if pd(j,t1,t2) then
begin
ans:=j;
st:=t1;
ed:=t2;
ch:=ct;
end;
end;
end;
//============================================================
procedure main;
begin
ans:=maxlongint;
qsortx(1,n);
work1;{<横着的捷径>}
qsorty(1,n);
work2;{<竖着的捷径>}
writeln(ans,' ',st,' ',ed,' ',ch);
end;
//============================================================
begin
assign(input,'p1332.in');reset(input);
assign(output,'p1332.out');rewrite(output);
init;
main;
close(input);close(output);
end.
题目来源:NDK 1332