标签:逆序数
题目大意:T代表T组样例,n个人以及k组为一个区域,然后接下来n个数表示n个人的位置,然后是两个置换:
//从归并排序到数列的逆序数对
#include <stdio.h>
#include <iostream>
using namespace std;
int g_nCount = 0;
void mergearray(int a[], int first, int mid, int last, int temp[])
{
int i = first, j = mid + 1;
int m = mid, n = last;
int k = 0;
while (i <= m && j <= n) //a[i] 前面的数 a[j] 后面的数
{
if (a[i] <= a[j])temp[k++] = a[i++];
else{
temp[k++] = a[j++];//a[j]和前面每一个数都能组成逆序数对
g_nCount += m - i + 1;
}
}
while (i <= m) temp[k++] = a[i++];
while (j <= n) temp[k++] = a[j++];
for (i = 0; i < k; i++) a[first + i] = temp[i];
}
void mergesort(int a[], int first, int last, int temp[])
{
if (first < last)
{
int mid = (first + last) / 2;
mergesort(a, first, mid, temp); //左边有序
mergesort(a, mid + 1, last, temp); //右边有序
mergearray(a, first, mid, last, temp); //再将二个有序数列合并
}
}
bool MergeSort(int a[], int n)
{
int *p = new int[n];
if (p == NULL)
return false;
mergesort(a, 0, n - 1, p);
delete[] p;
return true;
}
int main ()
{
int CASE,T,k,a[1005];
scanf("%d",&CASE);
for(int cas = 1; cas<=CASE; cas++){
scanf("%d %d",&T,&k);
g_nCount = 0;
int count2=0;
for(int i = 0; i < T; i++){
scanf("%d",&a[i]),a[i]=(a[i]-1)/k + 1;
int m = i / k + 1;
if(m>a[i])
count2=max(count2,i+1-(k*a[i]+1));
else if(m<a[i])
count2=max(count2,k*(a[i]-1)+1-(i+1));
}
MergeSort(a,T);
printf("Case %d: %d\n",cas,g_nCount-count2);
}
}
UVALive 6604 Airport Sort 【归并排序】【逆序数】
标签:逆序数
原文地址:http://blog.csdn.net/u010468553/article/details/38846343