Time Limit: 1000MS Memory Limit: 10000K
描述
对于一个序列中,”无序度”的度量,可以是次序颠倒的条目对的数量。例如,在字母序列”DAABEC”中,无序数为5,因为D比他右边的四个字母都大,E比它右侧的1个字母打。这种度量方法成为序列颠倒数。序列”AACEDGG”的逆序数是1(只有E和D),该序列几乎是有序的,然而序列”ZWQM”有6个颠倒(这种情况是最无序的,即完全逆序)
你将负责排列一个DNA strings序列(序列仅包含四种字母,A、C、G、T)。然而,你想要排列,且不是按字母顺序,而是按照“有序度”的顺序,从”最有序”排列到“最无序”。所有的strings具有相同长度。
输入
第一行包含两个整数:一个正整数
n(0<n≤50)
给出了strings的长度;一个正整数
m(0<m≤100)
该处了strings的数量。之后是
m
行strings,每行string长度为
输出
输出是输入strings的列表,从”最有序”排列到”最无序”。两个strings的无序度可能相同,此时按照原来的顺序输出即可。
输入样例
10 6
AACATGAAGG
TTTTGGCCAA
TTTGGCCAAA
GATCAGATTT
CCCGGGGGGA
ATCGATGCAT
输出样例
CCCGGGGGGA
AACATGAAGG
GATCAGATTT
ATCGATGCAT
TTTTGGCCAA
TTTGGCCAAA
思路
1、逆序数可从后往前扫描,每次记录ACG出现的次数,当前字母比前一刻扫描的字母大时,逆序数加上之前小字母出现的总次数
<—————————
序列 T T G G C C A A
逆序数 6 6 4 4 2 2 0 0
2、字符串最长50,所以char型数组要申请51,因为字符串末尾的’\n’
C++实现
#include <iostream>
#include <algorithm>
typedef struct DNA
{
int count;// 逆序数的个数
char DNAStr[110];
} DNA;
int N;
int SIZE;
int countA,countC,countG;
/** 计算DNA字符串的逆序数 */
int getDNAInversionNumber(char* dnaStr)
{
int count = 0;
countA = countC = countG = 0;
for(int j = SIZE-1; j >= 0; j--)
{
switch(dnaStr[j])
{
case 'A':
countA++;
break;
case 'C':
countC++;
count += countA;
break;
case 'G':
countG++;
count += countA;
count += countC;
break;
case 'T':
count += countA;
count += countC;
count += countG;
break;
}
}
return count;
}
int cmp(const void* a, const void* b)
{
DNA* DNA_A = (DNA*)a;
DNA* DNA_B = (DNA*)b;
return (DNA_A->count) - (DNA_B->count);
}
int main()
{
using namespace std;
while(cin >> SIZE >> N)
{
DNA* dnas = new DNA[N];
for(int i = 0; i < N; i++)
{
cin >> dnas[i].DNAStr;
dnas[i].count = getDNAInversionNumber(dnas[i].DNAStr);
}
qsort(dnas, N, sizeof(DNA), cmp);
for(int i = 0; i < N; i++)
{
cout << dnas[i].DNAStr << endl;
}
}
return 0;
}