标签:逆序数
题目大意: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