POJ1007 DNA Sorting
题目来源:http://poj.org/problem?id=1007
题目大意:
有一种“无序度”(unsortedness)为:在一个序列中,大小关系与位置关系不符的元素对的个数。例如:字母序列“DAABEC”的无序度为5.因为D比它后面的4个字母大,E比它后面的一个字母大。这种未排序度的名称叫逆序对。序列“AACEDGG”只有一个逆序对(E和D),它是几乎有序的。而“ZWQM”有6个逆序对,是完全逆序的。
你的任务是对一些DNA序列进行排序。序列仅含四种字母:A、C、G、T,然后不是按字典序排序,而是按无序度排序,从“最有序”至“最无序”。所有的字符串的长度相等。
输入:第一行是两个正整数:n(0<n<=50),每个字符串的长度。m(0<m<=100)字符串的个数。然后是m行数据,每行含一个长度为n的字符串。
输出:输出所有输入的字符串,按“无序度”排序,从“最有序”到“最无序”,当两个字符串的无序度相等时,按输入顺序排序。
Sample Input
10 6 AACATGAAGG TTTTGGCCAA TTTGGCCAAA GATCAGATTT CCCGGGGGGA ATCGATGCAT
Sample Output
CCCGGGGGGA AACATGAAGG GATCAGATTT ATCGATGCAT TTTTGGCCAA TTTGGCCAAA
本题实际就是求字符串的逆序对数目,算法导论上见过相关习题,所以直接用了里面的思想:分治法。借鉴归并排序的方法,整个序列的逆序对数目=前半段的逆序对数目+后半段的逆序对数目+前半段中比后半段中字母大的个数(合并两组序列时可算得)
1 ////////////////////////////////////////////////////////////////////////// 2 // POJ1007 DNA Sorting 3 // Memory: 252K Time: 16MS 4 // Language: C++ Result: Accepted 5 ////////////////////////////////////////////////////////////////////////// 6 7 #include <iostream> 8 9 using namespace std; 10 11 char oriList[100][50]; //原始DNA数据 12 char sortedList[100][50]; //排序后DNA数据 13 char str[50]; 14 int rpc[100]; //记录逆序对数的数组 15 int order[100]; //记录顺序的数组 16 17 //归并排序并计算逆序对数 18 int merge (int index, int start, int end) { 19 if (start == end) { 20 return 0; 21 } 22 int mid = (start + end) / 2; 23 int c1 = merge(index, start, mid); 24 int c2 = merge(index, mid + 1, end); 25 int i = start; 26 int j = mid + 1; 27 int count = 0; 28 int k = 0; 29 while (i <= (mid + 1) && j <= (end + 1)) { 30 if (i == (mid + 1)) { 31 str[k] = sortedList[index][j]; 32 k++; 33 j++; 34 continue; 35 } else if (j == (end + 1)) { 36 str[k] = sortedList[index][i]; 37 k++; 38 i++; 39 continue; 40 } 41 if (sortedList[index][i] > sortedList[index][j]) { 42 str[k] = sortedList[index][j]; 43 j++; 44 k++; 45 count += (mid - i + 1); 46 } else { 47 str[k] = sortedList[index][i]; 48 i++; 49 k++; 50 } 51 } 52 for (k = 0; k < end - start + 1; k++) { 53 sortedList[index][start + k] = str[k]; 54 } 55 return c1 + c2 + count; 56 } 57 58 int main() { 59 int n, m; 60 cin >> n >> m; 61 for (int i = 0; i < m; i++) { 62 for (int j = 0; j < n; j++) { 63 cin >> oriList[i][j]; 64 sortedList[i][j] = oriList[i][j]; 65 } 66 order[i] = i; 67 } 68 for (int i = 0; i < m; i++) { 69 rpc[i] = merge(i, 0, n - 1); 70 } 71 for (int i = 0; i < m; i++) { 72 for (int j = i + 1; j < m; j++) { 73 if (rpc[i] > rpc[j]) { 74 int temp = rpc[i]; 75 rpc[i] = rpc[j]; 76 rpc[j] = temp; 77 temp = order[i]; 78 order[i] = order[j]; 79 order[j] = temp; 80 } 81 } 82 } 83 for (int i = 0; i < m; i++) { 84 for (int j = 0; j < n; j++) { 85 cout << oriList[order[i]][j]; 86 } 87 cout << endl; 88 } 89 return 0; 90 }