您的位置:首页 > 其它

微软100题(92)捣乱分子(即逆序对的题目)

2015-06-17 14:33 239 查看
1.多人排成一个队列,我们认为从低到高是正确的序列,但是总有部分人不遵守秩序。
如果说,前面的人比后面的人高(两人身高一样认为是合适的),
那么我们就认为这两个人是一对“捣乱分子”,比如说,现在存在一个序列:
176, 178, 180, 170, 171
这些捣乱分子对为
<176, 170>, <176, 171>, <178, 170>, <178, 171>, <180, 170>, <180, 171>,
那么,现在给出一个整型序列,请找出这些捣乱分子对的个数(仅给出捣乱分子对的数目即可,不用具体的对)
要求:
输入:
为一个文件(in),文件的每一行为一个序列。序列全为数字,数字间用”,”分隔。
输出:
为一个文件(out),每行为一个数字,表示捣乱分子的对数。
详细说明自己的解题思路,说明自己实现的一些关键点。
并给出实现的代码 ,并分析时间复杂度。
限制:
输入每行的最大数字个数为100000个,数字最长为6位。程序无内存使用限制。

思路:寻找逆序对数目,对每一行的数据,应用边归并排序边统计的算法可以优化复杂度
#include <iostream>
#include <vector>
using namespace std;

int InverseParisRes(vector<int> &data,vector<int> ©,int start,int end);
int InverseParis(vector<int> &data)
{
	size_t num = data.size();
	int count = 0;
	vector<int> copy(num,0);
	for (size_t i = 0; i < num; ++i)
	    copy[i] = data[i];
	count = InverseParisRes(data,copy,0,num-1);

	return count;
}
int InverseParisRes(vector<int> &data,vector<int> ©,int start,int end)
{
	if(start == end)
	{
		copy[start] = data[start];
		return 0;
	}
	int middle = (end - start)/2;
	int left = InverseParisRes(copy,data,start,start+middle);
	int right = InverseParisRes(copy,data,start+middle+1,end);
	int i = start + middle;
	int j = end,k = end;
	int count = 0;
	while (i >= start && j >= start+middle+1)
	{
		if(data[i] > data[j])
		{
			copy[k--] = data[i--];
			count += j-start-middle;
		}
		else
		{
			copy[k--] = data[j--];
		}
	}
	while (i >= start)
	    copy[k--] = data[i--];
	while (j >= start+middle+1)
		copy[k--] = data[j--];

	return left + right + count;
}

int main()
{
	int a[4]={7,5,6,4};
	vector<int> data(a,a+4);
	cout<<InverseParis(data)<<endl;
	
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: