【SSLGZ 1549】水王争霸

问题描述
众所周知,IOIForum有很多水王,他们的发贴数是如此之多,以至于必须要用高精度数才能保存。
  为了迎接国庆,IOIForum决定举行一次水王争霸赛,比赛的规则是将这些水王截止到2003年9月30日23时59分59秒这一刻所发的总贴数从大到小进行排序。每个水王当然都想取得尽量靠前的名次,所以他们竭尽全力,不择手段地进行灌水。
  终于,激动人心的一刻到来了,2003年10月1日0时0分0秒,你作为裁判得到了每个水王的发贴数,现在,你的任务是公正地把这些水王按照发贴数从大到小进行排序。
输入
输入的第一行是一个1到1000的整数N,表示总共有N位水王参加了争霸赛。
  以下依次给出每位水王的描述,一位水王的描述占据两行,第一行为一个仅由字母和数字组成的长度不超过20的字符串,代表这个水王的ID,第二行一个高精度的整数(非负数),代表这个水王的发贴数。注意,这个整数的首位没有不必要的0。
  考虑到IOIForum的数据库是有限的,所有水王发贴数的总长度(注意,是总长度而不是总和)不会超过10000。
  除了子母、数字和必要的换行,输入中不会出现空格等字符。
输出
依次输出按照发贴数从大到小排好序的各位水王的ID,每个ID占据单独的一行。不能有任何多余的字符。若几个ID的发贴数相同,则按照ID的字典顺序先后排列。
样例输入
6
lowai
1534534124561243453
zhouyuan
23453265344
Maolaoda
23442353452342
BuTaoCaiGuai
7568784573464
ArthurKing
97534892734723947
hyyylr
623893451
样例输出
lowai
ArthurKing
Maolaoda
BuTaoCaiGuai
zhouyuan
hyyylr
算法讨论
总体来说是比较水的,但有些细节要注意,比如数字的字符串不能直接比较,要长度一样的才能直接比较,当两个数字相同时要按名字的字典顺序输出,这个就可以直接比较,因为是从头开始逐位比较。

const
  maxn=1000;
var
  a:array[1..maxn,1..2] of ansistring;
  i,n:longint;

function prepare(x,y:ansistring):boolean;
var
  l1,l2:longint;
begin
  l1:=length(x);
  l2:=length(y);
  if l1>l2
    then exit(true)
    else if l1then exit(false)
           else if x>y
                  then exit(true)
                  else exit(false)
end;

procedure qsort(l,r:longint);
var
  i,j:longint;
  m,m1,t:ansistring;
begin
  i:=l; j:=r;
  m:=a[(l+r) div 2,2];
  m1:=a[(l+r) div 2,1];
  repeat
    while (prepare(a[i,2],m)) or (a[i,2]=m) and (a[i,1]do
      inc(i);
    while (prepare(m,a[j,2])) or (a[j,2]=m) and (a[j,1]>m1) do
      dec(j);
    if i<=j
      then begin
             t:=a[i,2]; a[i,2]:=a[j,2]; a[j,2]:=t;
             t:=a[i,1]; a[i,1]:=a[j,1]; a[j,1]:=t;
             inc(i); dec(j)
           end;
  until i>j;
  if lthen qsort(l,j);
  if ithen qsort(i,r)
end;

begin
  readln(n);
  for i:=1 to n do
    begin
      readln(a[i,1]);
      readln(a[i,2])
    end;
  qsort(1,n);
  for i:=1 to n do
    writeln(a[i,1])
end.


Pixiv ID:61933670

你可能感兴趣的:(排序,字符串)