Time Limit: 1000MS Memory Limit: 10000K
描述
對於一個序列中,”無序度”的度量,可以是次序顛倒的條目對的數量。例如,在字母序列”DAABEC”中,無序數爲5,因爲D比他右邊的四個字母都大,E比它右側的1個字母打。這種度量方法成爲序列顛倒數。序列”AACEDGG”的逆序數是1(只有E和D),該序列幾乎是有序的,然而序列”ZWQM”有6個顛倒(這種情況是最無序的,即完全逆序)
你將負責排列一個DNA strings序列(序列僅包含四種字母,A、C、G、T)。然而,你想要排列,且不是按字母順序,而是按照“有序度”的順序,從”最有序”排列到“最無序”。所有的strings具有相同長度。
輸入
第一行包含兩個整數:一個正整數
輸出
輸出是輸入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;
}