http://poj.org/problem?id=2299
分析一个特定的排序算法。这一算法通过交换相邻的两个数来处理一个由不同整数组成的数列,直到数组升序排好序为止。
Your task is to determine how many swap operations it needs to perform in order to sort a given input sequence. n < 500,000
分析:使用类似归并排序的方法
#pragma warning (disable:4786)
#include<iostream>
#include<algorithm>
using namespace std;
#define MAX 500000
int re[MAX + 10];
//归并排序暂存数据的数组
int tmp[MAX + 10];
long long sum;
//递归求逆序数对
long long reverse ( int l, int r ){
if( l >= r )
return 0;
else {
int m = ( l + r ) / 2;
//将数组分为两个size一样的数组,分别对其进行归并排序(在此过程中记录逆序数对个数)
sum = reverse( l, m ) + reverse( m + 1, r );
//对两个已排好序的数组归并排序,并计算其逆序数
int l1 = l, l2 = m + 1, size = 0;
while( l1 <= m && l2 <= r ){
//如果当前最小的元素是前一个子数组中的,则逆序数不变
if( re[l1] <= re[l2] ){
tmp[size] = re[l1];
size ++;
l1 ++;
}
//如果当前最小的元素是后一个子数组中的,则逆序数的个数增加数量 =(前一个子数字尚未被处理过的元素个数)
else {
tmp[size] = re[l2];
size ++;
sum = sum + m - l1 + 1;
l2 ++;
}
}
while( l1 <= m ){
tmp[size] = re[l1];
size ++;
l1 ++;
}
while( l2 <= r ){
tmp[size] = re[l2];
size ++;
l2 ++;
}
int i, j = 0;
for( i = l; i <= r; i ++, j ++ )
re[i] = tmp[j];
return sum;
}
}
int main(){
int n,i,j,t;
while( scanf("%d",&n) && n ){
sum = 0;
for( i = 0; i < n; i ++ ){
scanf( "%d",&re[i] );
}
printf( "%lld\n", reverse( 0, n - 1 ) );
}
return 0;
}