总时间限制: 

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,结果格式错误***。

OPJ2018年算法课第二次作业:F.求逆序对数

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;
}

 

相关文章:

  • 2022-12-23
  • 2021-12-30
  • 2021-08-24
  • 2021-07-19
  • 2021-09-07
  • 2021-09-01
  • 2021-08-19
  • 2022-01-24
猜你喜欢
  • 2021-08-26
  • 2022-02-13
  • 2021-07-06
相关资源
相似解决方案