百练2299:Ultra-QuickSort(归并排序求逆序对数)

题目来源:http://bailian.openjudge.cn/practice/2299/

2299:Ultra-QuickSort

总时间限制: 7000ms      内存限制: 65536kB

描述

In this problem, you have to analyze a particular sortingalgorithm. The algorithm processes a sequence of n distinct integers byswapping two adjacent sequence elements until the sequence is sorted inascending order. For the input sequence 

9 1 0 5 4 ,


Ultra-QuickSort produces the output 

0 1 4 5 9 .


Your task is to determine how many swap operations Ultra-QuickSort needs toperform in order to sort a given input sequence.

输入

The input contains several test cases. Every test casebegins with a line that contains a single integer n < 500,000 -- the lengthof the input sequence. Each of the the following n lines contains a singleinteger 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input isterminated by a sequence of length n = 0. This sequence must not be processed.

输出

For every input sequence, your program prints a singleline containing an integer number op, the minimum number of swap operationsnecessary to sort the given input sequence.

样例输入

5

9

1

0

5

4

3

1

2

3

0

样例输出

6

0

-----------------------------------------------------

解题思路

此题就是求解一种O(nlogn)的排序算法

在排序的同时计算逆序对个数

此处采用归并排序算法

-----------------------------------------------------

代码

#include
#include
#include
using namespace std;

long long int ans = 0;							// 逆序对数

void merge(vector &v, int l, int m, int r)	// 改vector的函数声明的时候要用引用,否则改不了
	// 将v中的[l,m]和[m+1,r]两个有序组合并成一个有序组
{
	vector v1;
	int i=l, j=m+1;
	int cnt = 0;							// 发生j>i的次数
	while (i<=m && j<=r)
	{
		if (v.at(i) <= v.at(j))
		{
			v1.push_back(v.at(i));
			i++;
		}
		else
		{
			v1.push_back(v.at(j));
			ans += j-i-cnt;						// 移动m次等价于m对逆序对
			cnt++;
			j++;								// 先计算,再++!!!!!
		}
	}
	while (i<=m)
	{
		v1.push_back(v.at(i));
		i++;
	}
	while (j<=r)
	{
		v1.push_back(v.at(j));
		j++;
	}
	j = 0;
	for (i=l; i<=r; i++)
	{
		v.at(i) = v1.at(j++);
	}
}

void mergeSort(vector &v, int l, int r)
{
	if (r == l)
	{
		return;
	}
	int m = (l+r)/2;
	mergeSort(v, l, m);
	mergeSort(v, m+1, r);
	merge(v, l, m, r);
}

int main()
{
	// 采用控制台输入
	int len = 1, i=0, tmp=0;
	vector ansVector;
	while (len != 0)
	{
		ans = 0;
		cin >> len;
		if (len == 0)
		{
			continue;
		}
		// read in the data
		vector arr;
		for (i=0; i> tmp;
			arr.push_back(tmp);
		}
		// merge sort
		mergeSort(arr, 0, arr.size()-1);
		ansVector.push_back(ans);
	}
	// output answer vector
	vector::iterator it;
	for (it=ansVector.begin(); it!=ansVector.end(); it++)
	{
		cout << *it << endl;
	}
	return 0;
}


你可能感兴趣的:(百练OJ/poj)