jzoj1520 破碎的路径

22 篇文章 0 订阅
4 篇文章 0 订阅

Description

比尔去很多地方旅游过。他在旅游的同时留下了很多简短的旅行笔记。笔记的形式是这样的:
出发地 目的地
如下面就是三条合法的note:
SwimmingPool OldTree
BirdsNest Garage
Garage SwimmingPool
在某一次搬家的时候,比尔的笔记本不小心散架了。于是他的笔记的顺序被完全打乱了。他想请你帮个忙,帮他把这些笔记的顺序整理好,先写的笔记在前面。幸运的是,同一个地方比尔至多只去过一次。也就是说,在这些笔记当中,一个地方至多出现两次,一次作为目的地,一次作为出发地。

Input

第一行是一个整数n,表示笔记的条数。N <= 12000。接下来有n行,每行一条笔记。笔记的两个单词的长度都不会超过15,两个单词之间以一个空格分隔。

Output

输出整理好顺序的笔记.

Sample Input

3
SwimmingPool OldTree
BirdsNest Garage
Garage SwimmingPool

Sample Output

BirdsNest Garage
Garage SwimmingPool
SwimmingPool OldTree

Hint

【限制】
对于50%的数据,n <= 1000。
对于100%的数据,n <= 12000。

算法讨论
二分+排序。把出发点数组a和目的地数组b分别排序,排序时连同a的日记编号一同排序,如果a[i]在b中没有出现,那么就是起点,s[i]就是第一条,再把b[s[i]]在a中寻找,就知道下一条路线,同理重复n次。

    while a[i]<t do inc(i);
    while a[j]>t do dec(j);
    if i<=j then
      begin
        z:=a[i];a[i]:=a[j];a[j]:=z;
        c:=s[i];s[i]:=s[j];s[j]:=c;
        inc(i);dec(j);
      end;
  until i>j;
  if l<j then kp(l,j);
  if i<r then kp(i,r);
end;
procedure kpp(l,r:longint);
var
  i,j:longint;
  t,z:string;
begin
  i:=l;j:=r;
  t:=b[(l+r) div 2];
  repeat
    while b[i]<t do inc(i);
    while b[j]>t do dec(j);
    if i<=j then
      begin
        z:=b[i];b[i]:=b[j];b[j]:=z;
        inc(i);dec(j);
      end;
  until i>j;
  if l<j then kpp(l,j);
  if i<r then kpp(i,r);
end;
var
  i,j:longint;
begin
  readln(n);
  for i:=1 to n do
    begin
      readln(y[i]);
      x[i]:=copy(y[i],1,pos(' ',y[i])-1);
      delete(y[i],1,pos(' ',y[i]));
      a[i]:=x[i];
      b[i]:=y[i];
      s[i]:=i;
    end;
  kp(1,n);
  kpp(1,n);

  for i:=1 to n do
    if b[ef(a[i])]<>a[i] then
      begin
        j:=s[i];
        break;
      end;
  for i:=1 to n do
    begin
      writeln(x[j],' ',y[j]);
      j:=find(y[j]);
    end;
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值