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

 

1: 
#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: }

相关文章: