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 }
View Code
posted @ 2013-07-30 19:42  小菜刷题史  阅读(453)  评论(0编辑  收藏  举报