http://poj.org/problem?id=1007
求逆序数的方法:
1、此题每个string只有4种字母,所以可以用类似counting sort的方法来以逆序扫描字符串,并以a[1...3]记录相应字符串组的个数,计算每位数与其后面几位的逆序数。复杂度n。但输入若没有限制就不能靠a[1...3]这样做了,那样的话可能每扫描一个字符++的数组位很多,需要判断的分支也很多,因此复杂度太高。
2、利用merge sort求逆序数n*lgn,对所有字符串的逆序数排序(这里用multimap简单代替)
Description
One measure of ``unsortedness'' in a sequence is the number of pairs of entries that are out of order with respect to each other. For instance, in the letter sequence ``DAABEC'', this measure is 5, since D is greater than four letters to its right and E is greater than one letter to its right. This measure is called the number of inversions in the sequence. The sequence ``AACEDGG'' has only one inversion (E and D)---it is nearly sorted---while the sequence ``ZWQM'' has 6 inversions (it is as unsorted as can be---exactly the reverse of sorted).
You are responsible for cataloguing a sequence of DNA strings (sequences containing only the four letters A, C, G, and T). However, you want to catalog them, not in alphabetical order, but rather in order of ``sortedness'', from ``most sorted'' to ``least sorted''. All the strings are of the same length.
Input
The first line contains two integers: a positive integer n (0 < n <= 50) giving the length of the strings; and a positive integer m (0 < m <= 100) giving the number of strings. These are followed by m lines, each containing a string of length n.
Output
Output the list of input strings, arranged from ``most sorted'' to ``least sorted''. Since two strings can be equally sorted, then output them according to the orginal order.
Sample Input
10 6
AACATGAAGG
TTTTGGCCAA
TTTGGCCAAA
GATCAGATTT
CCCGGGGGGA
ATCGATGCAT
Sample Output
CCCGGGGGGA
AACATGAAGG
GATCAGATTT
ATCGATGCAT
TTTTGGCCAA
TTTGGCCAAA
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
#include <fstream>
7:
namespace std ;
9:
//逆序扫描字符串求逆序数
//复杂度n
int n )
13: {
14: __int64 cnt ;
//a[1]:A , a[2]:A,C , a[3]:A,C,G 的个数
int i ;
17:
//从后往前扫描,计算每位数与其后面几位的逆序数
19: cnt = 0 ;
for( i=n-1 ; i>=0 ; --i )
21: {
switch(str[i])
23: {
//与其后面不会形成逆序对
25: ++a[1] ;
26: ++a[2] ;
27: ++a[3] ;
break ;
//与其后面的A形成逆序,所以逆序数要加上其后A的个数
30: ++a[2] ;
31: ++a[3] ;
32: cnt += a[1] ;
break ;
//与其后面的A、C形成逆序,所以逆序数要加上其后A、C的个数
35: ++a[3] ;
36: cnt += a[2] ;
break ;
//与其后面的A、C、G形成逆序,所以逆序数要加上其后A、C、G的个数
39: cnt += a[3] ;
break ;
41: }
42: }
return cnt ;
44: }
45:
//**********************************
47:
48: __int64 inversionNum = 0 ;
49:
int re )
51: {
int le = rb-1 ;
int tmpStart = lb ;
int tmpEnd = re ;
int tmpIndex = lb ;
while( lb<=le && rb<=re )
57: {
if( a[lb] <= a[rb] )
59: tmpArr[tmpIndex++] = a[lb++] ;
else
61: {
62: tmpArr[tmpIndex++] = a[rb++] ;
63: inversionNum += le-lb+1 ;
64: }
65: }
66:
while(lb<=le)
68: tmpArr[tmpIndex++] = a[lb++] ;
while(rb<=re)
70: tmpArr[tmpIndex++] = a[rb++] ;
71:
while(tmpStart<=tmpEnd)
73: {
74: a[tmpStart] = tmpArr[tmpStart] ;
75: ++tmpStart ;
76: }
77: }
78:
int e )
80: {
if(b>=e)
return ;
int mid = b+(e-b)/2 ;
84: Msort(a,tmpArr,b,mid) ;
85: Msort(a,tmpArr,mid+1,e) ;
86: Merge(a,tmpArr,b,mid+1,e) ;
87: }
88:
int n )
90: {
char[n+1] ;
92: Msort(a,tmpArr,0,n-1) ;
delete []tmpArr ;
94: }
95:
//**********************************
97:
void run1007()
99: {
);
101:
int n,m ;
103: string tmpStr ;
104: multimap< __int64 , string > strMap ;
105: multimap< __int64 , string >::iterator iter ;
106:
107: in>>n>>m ;
108:
//末尾'0'
110:
//不能用gets(a),不然会从第一行输入的末尾开始,其末尾为换行符,而gets不会读入换行符
//所以gets读入的第一行字符为空字符
113: tmpStr = a ;
114: MergeSort(a,n) ;
115: strMap.insert( make_pair(inversionNum,tmpStr) ) ;
116: inversionNum = 0 ;
117: }
118:
for( iter=strMap.begin() ; iter!=strMap.end() ; ++iter )
120: cout<<iter->second<<endl ;
121:
delete []a ;
123: }
124:
125:
void run1007_1()
127: {
);
129:
int n,m ;
131: string tmp ;
132: multimap< __int64 , string > strMap ;
133: multimap< __int64 , string >::iterator iter ;
134:
135: in>>n>>m ;
136:
//末尾'0'
138:
//不能用gets(a),不然会从第一行输入的末尾开始,其末尾为换行符,而gets不会读入换行符
//所以gets读入的第一行字符为空字符
/*
//这样会导致strMap中所有的second都是最后一个读入的字符串
//因为作为second的a每次输入时都会被改变,其并没有复制
__int64 count = GetInversionCount(a,n) ;
strMap.insert( make_pair(count,a) ) ;
*/
147: tmp = a ;
148: __int64 count = GetInversionCount(a,n) ;
149: strMap.insert( make_pair(count,tmp) ) ;
150:
151: }
152:
for( iter=strMap.begin() ; iter!=strMap.end() ; ++iter )
154: cout<<iter->second<<endl ;
155:
delete []a ;
157: }