逆序对
来源:互联网 发布:高级的数据分析算法 编辑:程序博客网 时间:2024/04/27 18:30
Time Limit: 2 Seconds Memory Limit: 65536 KB
现在给定一个有 N 个数的数列 Ai。若对于 i < j,有 Ai > Aj,则称 (i, j) 为数列的一个逆序对。
例如,<2, 3, 8, 6, 1> 有五个逆序对,分别是 (1, 5), (2, 5), (3, 4), (3, 5), (4, 5)。
现在请你求出一个给定数列的逆序对个数。
提示:排序算法可以解决这个问题。
输入格式
一个整数 T,表示有多少组测试数据。
每组测试数据第一行是一个正整数 N (1 <= N <= 100000),表示数列中有 N 个数字。
接下来一行包含 N 个正整数,代表对应的数列。
保证所有正整数小于 100000000。
输出格式
对于每组数据,输出一行,表示逆序对的个数。
样例输入
152 3 8 6 1
样例输出
5
思路: 归并排序求逆序数。合并排序在合并阶段分为两个序列(设L[]与R[]),L序列与R序列分别是经过排序的。每次从两个序列中取值时分两种情况:(1)从L中取值,这样取出的值的逆序数为0;(2)从R中取值,这时,取出的值的逆序数为L中剩余元素的个数。
#include <stdio.h>int arrTmp[100010]; long long num;void Merge(int arr[], int low, int mid, int high){int i = low, j = mid + 1, k = low; while (i <= mid&&j <= high){if (arr[i] <= arr[j]){arrTmp[k++] = arr[i++];}else{arrTmp[k++] = arr[j++];num += mid - i + 1;}}while (i <= mid){arrTmp[k++] = arr[i++];}while (j <= high){arrTmp[k++] = arr[j++];}for (i = low; i <= high; i++){arr[i] = arrTmp[i];}}void MergeSort(int arr[], int low, int high){if (low<high){int mid = (low + high) / 2;MergeSort(arr, low, mid);MergeSort(arr, mid + 1, high);Merge(arr, low, mid, high);}}int main(){int T;while (scanf("%d", &T) != EOF){for (int i = 0; i<T; i++){int N;num = 0;scanf("%d", &N);int arr[100000];for (int j = 0; j<N; j++){scanf("%d", &arr[j]);}MergeSort(arr, 0, N - 1);printf("%lld\n", num);}}}
0 0
- 逆序数 & 逆序对
- 逆序对
- 逆序对
- 逆序对
- 逆序对
- 逆序对
- 逆序对
- 逆序对
- 逆序对
- 逆序对
- 逆序对
- 逆序对
- 逆序对
- 逆序对
- 逆序对
- 逆序对
- 逆序对
- 逆序对
- 简单的足球游戏——for循环的应用,输入输出函数的区别
- PKU ACM经典50题
- NYOJ 60 谁获得了最高奖学金【结构体】
- Codeforces Round #264 (Div. 2) C
- 异常:Only the original thread that created a view hierarchy can touch its views的解决办法
- 逆序对
- 数据库原理第一章总结
- [MySQL]-->查询5天之内过生日的同事中的跨年问题的解决过程
- 协议
- 小米笔试题
- 美国宣布转基因有毒,鉴别有方
- 搜狗2014年笔试题-两递增数组A和B,求A[i]+B[j]中前k个最小值(Java)
- socket的半包,粘包与分包的问题
- 我的25年人生轨迹:从淡雅农村到繁华都市,未来又将到哪里呢