总时间限制:
500ms
内存限制:
65536kB
描述
对于一个长度为N的整数序列A,满足i < j 且 Ai > Aj.的数对(i,j)称为整数序列A的一个逆序
请求出整数序列A的所有逆序对个数
输入
输入包含多组测试数据,每组测试数据有两行
第一行为整数N(1 <= N <= 20000),当输入0时结束
第二行为N个整数,表示长为N的整数序列
输出
每组数据对应一行,输出逆序对的个数
样例输入
5
1 2 3 4 5
5
5 4 3 2 1
1
1
0
样例输出
0
10
0
解题思路详解:
主要用到的算法是归并排序的算法,递归。在归并排序的过程中,通过合并两个小段就能统计出逆序对的个数。例如:1,2,3;1,4;合并,程序流程如下:
1. 初始时刻,pos1=0,pos2=0;都指向两个数组的第一个数,定义一个长度为5的数组temp[5],因为两个数组一共5个数。
2. 1=1;pos1++;temp[0]=1;
3. 2>1; pos2++; temp[1]=1; 这个时候选择了第二个数组的第一个数,且第一个数组有剩余值,说明这些剩余值都将与第二个数组 的第一个数是逆序的,找到2个逆序对。
4. 2<4; pos1++;temp[2]=2;
5. 3<4; pos1++;temp[3]=3;
6. 仅有数值4;pos2++;temp[4]=4;
仔细思考这个流程之后,写出就不是什么难事了,注意,题目给了输出格式要求,必须是每一行一个数,因此要空格,本来一次AC,结果格式错误***。

C++代码
|
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <math.h>
#include <algorithm>
#include <fstream>
#include <map>
using namespace std;
class Solution2_F {
public:
int Reverse_order() {
//归并排序
Merge_sort(0, N - 1);
return res;
}
void Merge_sort(int begin, int end) { //[0,N]闭区间
if (end == begin) return;
if (end == begin + 1) {
if (data[begin] > data[end]) {
swap(data[begin], data[end]);
res++;
}
return;
}
int mid = (begin + end) / 2;
Merge_sort(begin, mid);
Merge_sort(mid + 1, end);
Merge(begin, mid - begin + 1, mid + 1, end - mid);
}
void Merge(int pos1, int l1, int pos2, int l2) {//pos1开始的l1个数和pos2开始的l2个数合并
int begin = pos1;
vector<int> temp(l1 + l2, 0);
//判断合并过程中出现了几个逆序对
int pos = 0;
while (l1 > 0 || l2 > 0) {
if (l1 > 0 && l2 > 0) {
if (data[pos1] > data[pos2]) {
temp[pos] = data[pos2];
pos2++; l2--;
res += l1;
}
else {
temp[pos] = data[pos1];
pos1++; l1--;
}
}
else if (l1 > 0 && l2 == 0) {
temp[pos] = data[pos1];
pos1++; l1--;
}
else {
temp[pos] = data[pos2];
pos2++; l2--;
}
pos++;
}
for (int i = begin; i < begin + int(temp.size()); i++) {
data[i] = temp[i - begin];
}
}
void get_data() {
cin >> N;
data = vector<int>(N, 0);
for (int i = 1; i <= int(data.size()); i++) {
cin >> data[i - 1];
}
res = 0;
}
int isOK() { return N != 0; }
private:
int N;
vector<int> data;
int res;
};
int main()
{
Solution2_F F;
F.get_data();
while (F.isOK()) {
cout << F.Reverse_order() << endl;
F.get_data();
}
return 0;
}
|