特长生模拟——DNA排序

来源:互联网 发布:sql server 版本查看 编辑:程序博客网 时间:2024/06/03 14:08

题目大意:
问题描述
逆序对的定义如下:
有一个数列{an},对于任意的ai < aj若i>j,则(ai,aj)为一个逆序对。我们定义一个序列的无序度为其中的逆序对个数。一对DNA只含有ACGT 4种碱基,现在我们定义A < C < G < T,那么对于一串DNA序列,我们就可以得到它的无序度。
因此,我们给出n个长度均为L的DNA序列,请你将他们按无序度递增的顺序输出。对于无序度相同的两个DNA序列,输入顺序在前的序列输出也在前。

1<=n<=10000 1<=L<=50

题解:
前缀和,
sum[i,1..3]分别表示前i个【A,C,G】有多少个。
a[i]表示DNA的无序度。b[i]表示DNA的序号。
然后就可以枚举s[i]。
对于s[i][j]我们分情况:
A:后面不可能有大于他的。
C:后面仅有A大于他,a[i]+(sum[l,1]-sum[j,1])
G:后面有A,C大于他,a[i]+(sum[l,1]-sum[j,1])+(sum[l,2]-sum[j,2])
T:后面有A,C,G大于他,a[i]+(sum[l,1]-sum[j,1])+(sum[l,2]-sum[j,2])+(sum[l,3]-sum[j,3])
这样就可以得出无序度。
然后排序输出,排序时注意大小相等时,序号优先小的。
时间复杂度:O(2NL+N)

var    a,b:array [0..10001] of longint;    sum:array [0..51,1..3] of longint;    s:array [0..10001] of string;    i,j,k,n,l:longint;procedure qsort(l,r:longint);var    i,j,mid,midn:longint;begin    if l>=r then exit;    mid:=a[(l+r) div 2];    midn:=b[(l+r) div 2];    i:=l; j:=r;    repeat         while (a[i]<mid) or ((a[i]=mid) and (b[i]<midn)) do inc(i);         while (a[j]>mid) or ((a[j]=mid) and (b[j]>midn)) do dec(j);         if i<=j then         begin              a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];              b[0]:=b[i];b[i]:=b[j];b[j]:=b[0];              inc(i); dec(j);         end;    until i>j;    qsort(i,r);    qsort(l,j);end;begin    assign(input,'dna.in'); reset(input);    assign(output,'dna.out'); rewrite(output);    readln(l,n);    for i:=1 to n do    begin          readln(s[i]);          for j:=1 to l do          begin              for k:=1 to 3 do sum[j,k]:=sum[j-1,k];              case s[i][j] of                   'A':inc(sum[j,1]);                   'C':inc(sum[j,2]);                   'G':inc(sum[j,3]);              end;          end;          for j:=1 to l do              case s[i][j] of                   'C':a[i]:=a[i]+(sum[l,1]-sum[j,1]);                   'G':a[i]:=a[i]+(sum[l,1]-sum[j,1])+(sum[l,2]-sum[j,2]);                   'T':a[i]:=a[i]+(sum[l,1]-sum[j,1])+(sum[l,2]-sum[j,2])+(sum[l,3]-sum[j,3]);              end;          b[i]:=i;    end;    qsort(1,n);    for i:=1 to n do writeln(s[b[i]]);    close(input); close(output);end.