一个序列中的“未排序”的度量是相对于彼此顺序不一致的条目对的数量,例如,在字母序列“DAABEC”中,该度量为5,因为D大于右边是4个字母,E大于其右边的1个字母。该度量称为该序列的逆序数。序列“AACEDGG”只有一个逆序对(E和D),它几乎被排序好了,而序列“ZWQM”有6个逆序对,它是未排序的,恰好是反序。
你需要对若干个DNA序列(仅包含4个字母A、C、G和T的字符串)分类,注意是分类而不是按字母顺序排序,而是按照“最多排序”到“最小排序”的顺序排列,所有DNA序列的长度都相同。
输入格式:
第一行包含两个整数:n(0<n≤50)表示字符串长度,m(0<m≤100)表示字符串个数。后面是m行,每行包含一个长度为n的字符串。
输出格式:
按“最多排序”到“最小排序”的顺序输出所有字符串。若两个字符串的逆序对个数相同,按原始顺序输出它们。
输入样例:
10 6
AACATGAAGG
TTTTGGCCAA
TTTGGCCAAA
GATCAGATTT
CCCGGGGGGA
ATCGATGCAT
输出样例:
CCCGGGGGGA
AACATGAAGG
GATCAGATTT
ATCGATGCAT
TTTTGGCCAA
TTTGGCCAAA
代码:
#include<stdio.h>
#include<stdlib.h>
struct DNA
{
char a[100];
int sum;
int num;
}f[200];
int main()
{
int n,m,count;
int t;
scanf("%d %d",&n,&m);
for(int i=0;i<m;i++)
{
scanf("%s",&f[i].a);
count=0;
for(int j=0;j<n-1;j++)
{
for(int k=j;k<n;k++){
if(f[i].a[j]>f[i].a[k]){
count++; //计算无序对有几个
}
}
}
f[i].sum=count; //sum记录每个字符串各自的无序对
f[i].num=i; //记录无序对对应的字符串的下标
}
for(int i=0;i<m-1;i++) //将无序对数从大到小排序
{
for(int j=i;j<m;j++)
{
if(f[i].sum<=f[j+1].sum)
{
t=f[j+1].sum;
f[j+1].sum=f[i].sum;
f[i].sum=t; //无序对排序
t=f[j+1].num;
f[j+1].num=f[i].num;
f[i].num=t; //无序对被交换了,对应的代表字符串的下标也要被交换
}
}
}
for(int i=m-1;i>=0;i--){ //逆序输出,就是输出有序对数从大到小输出,因为跟无序对数相反
puts(f[f[i].num].a); //里面的下标是num记录的对应字符串的下标,字符串原本的位置是没有改变的
}
return 0;
}