对于一个包含N个非负整数的数组A[1..n],如果有i < j,且A[ i ]>A[ j ],则称( i , j )为数组A中的一个逆序对。
例如,数组(3,1,4,5,2)的逆序对有(3,1),(3,2),(4,2),(5,2),共4个。
输入格式:
输入包含若干组数据,第一行为一个整数T(0<T<20),表示共有T组测试数据。接下来每组测试数据包括两行,第一行只有一个整数m(0<m<=1000),表示数组有m个数,第二行为m个整数,数据之间用空格分隔。
输出格式:
对输入中的每组测试数据,输出一行对应逆序对的个数。
输入样例:
在这里给出一组输入。例如:
2
5
3 1 4 5 2
10
1 2 3 4 5 6 7 8 9 10
输出样例:
在这里给出相应的输出。例如:
4
0
代码长度限制
16 KB
时间限制
1000 ms
内存限制
64 MB
栈限制
8192 KB
cs
#include <stdio.h>
// 合并两个子数组并计数逆序对
int Count(int arr[], int temp[], int left, int mid, int right)
{
int i = left; // 左子数组的起始索引
int j = mid + 1; // 右子数组的起始索引
int k = left; // 临时数组的起始索引
int inv_count = 0;
while ((i <= mid) && (j <= right))
{
if (arr[i] <= arr[j])
{
temp[k++] = arr[i++];
}
else
{
temp[k++] = arr[j++];
inv_count += (mid - i + 1); // 统计逆序对
}
}
while (i <= mid)
{
temp[k++] = arr[i++];
}
while (j <= right)
{
temp[k++] = arr[j++];
}
for (i = left; i <= right; i++)
{
arr[i] = temp[i];
}
return inv_count;
}
// 递归地分割数组并计数逆序对
int Sort(int arr[], int temp[], int left, int right)
{
int mid, inv_count = 0;
if (left < right)
{
mid = (left + right) / 2;
inv_count += Sort(arr, temp, left, mid);
inv_count += Sort(arr, temp, mid + 1, right);
inv_count += Count(arr, temp, left, mid, right);
}
return inv_count;
}
// 主函数
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
int m;
scanf("%d", &m);
int arr[m];
for (int i = 0; i < m; i++)
{
scanf("%d", &arr[i]);
}
int temp[m];
int inv_count = Sort(arr, temp, 0, m - 1);
printf("%d\n", inv_count);
}
return 0;
}