您的位置:首页 > 其它

[Jobdu] 题目1348:数组中的逆序对

2014-04-18 15:19 225 查看
题目描述:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。输入:
每个测试案例包括两行:
第一行包含一个整数n,表示数组中的元素个数。其中1 <= n <= 10^5。
第二行包含n个整数,每个数组均为int类型。
输出:对应每个测试案例,输出一个整数,表示数组中的逆序对的总数。样例输入:
4
7 5 6 4

样例输出:
5


总的想法是归并排序,但是在计算逆序对时,有些小问题要考虑,不能漏掉某些元素,一种比较好的做法就在归并时当遇到第一个v[left] > v[right]时,cnt += 所有左边的left以后的元素的个数,而不是cnt += 1。代码如下:

#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;

int n;
vector<int> v;
unsigned long long cnt;

void merge(vector<int> &v, int low, int mid, int high) {
if (high <= low) return;
vector<int> tmp(high - low + 1);
int idx1 = low, idx2 = mid + 1;
int idx = 0;
while (idx1 <= mid && idx2 <= high) {
if (v[idx1] > v[idx2]) {
tmp[idx++] = v[idx2++];
cnt += mid - idx1 + 1;
} else {
tmp[idx++] = v[idx1++];
}
}

if (idx1 > mid)
while (idx < tmp.size()) tmp[idx++] = v[idx2++];

if (idx2 > high) {
while (idx < tmp.size()) tmp[idx++] = v[idx1++];
}

idx = 0;
while (idx < tmp.size())
v[low+idx] = tmp[idx++];
}

void mergeSort(vector<int> &v, int low, int high) {
if (high <= low) return;
int mid = (low + high) / 2;
mergeSort(v, low, mid);
mergeSort(v, mid + 1, high);
merge(v, low, mid, high);
}

int main() {
//freopen("a.in", "r", stdin);
while (cin >> n) {
v.resize(n);
cnt = 0;
for (int i = 0; i < n; ++i) {
cin >> v[i];
}
mergeSort(v, 0, v.size() - 1);
cout << cnt << endl;
}
return 0;
}
/**************************************************************
Problem: 1348
User: hupo250
Language: C++
Result: Accepted
Time:200 ms
Memory:2500 kb
****************************************************************/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: