首页 > 代码库 > UVALive 6604 Airport Sort 【归并排序】【逆序数】
UVALive 6604 Airport Sort 【归并排序】【逆序数】
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4615
题目大意:T代表T组样例,n个人以及k组为一个区域,然后接下来n个数表示n个人的位置,然后是两个置换:
- 每次只能交换相邻的两个人,每交换一次花费一秒。求出一个交换到要求的位置后花费的时间t1。
- 可以直接交换两个人的位置,花费的时间是两个人现在的位置差,可以同时交换,求交换到要求的位置后花费的时间t2。
求出t1比t2多花费的时间。
比如:
10 3
3 7 1 2 4 6 5 8 10 9
3 7 1 2 4 6 5 8 10 9
这一组样例:
第一个置换:
I. swap 7 with 1 ? 3 1 7 2 4 6 5 8 10 9
II. swap 7 with 2 ? 3 1 2 7 4 6 5 8 10 9
III. swap 7 with 4 ? 3 1 2 4 7 6 5 8 10 9
IV. swap 7 with 6 ? 3 1 2 4 6 7 5 8 10 9
V. swap 7 with 5 ? 3 1 2 4 6 5 7 8 10 9
VI. swap 10 with 9 ? 3 1 2 4 6 5 7 8 9 10 (now everyone is where they are supposed to be)
II. swap 7 with 2 ? 3 1 2 7 4 6 5 8 10 9
III. swap 7 with 4 ? 3 1 2 4 7 6 5 8 10 9
IV. swap 7 with 6 ? 3 1 2 4 6 7 5 8 10 9
V. swap 7 with 5 ? 3 1 2 4 6 5 7 8 10 9
VI. swap 10 with 9 ? 3 1 2 4 6 5 7 8 9 10 (now everyone is where they are supposed to be)
一共花费了6秒
第二个置换:
直接交换位置,那么花的时间最多的就是:
3 7 1 2 4 6 5 8 10 9
5秒。
所以第二个置换比第一个置换少了1秒。
比赛的时候遇到这个题目,第二个置换可以用贪心直接搞出来,但是第一个不会搞。
后来看题解说是归并排序可以搞出来。发现原来归并排序求逆序数竟然能这么用..........
a[i] =( a[i] -1 ) / k + 1 将 a[i] 进行了一定变换,然后可以求逆序数了。
//从归并排序到数列的逆序数对 #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 【归并排序】【逆序数】
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。