Ultra-QuickSort
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 39468 | Accepted: 14221 |
Description
![](https://i-blog.csdnimg.cn/blog_migrate/b3530eaa8fa98ef394d3639722240a8c.jpeg)
Ultra-QuickSort produces the output
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.
Input
The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.
Output
For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.
Sample Input
5 9 1 0 5 4 3 1 2 3 0
Sample Output
6 0 AC代码:#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define M 5000010 __int64 cur=0; int a[M],temp[M]; void mergesort(int *a, int first, int last, int *temp) { if(first==last) return; if(first<last) { int i= first,p = first; int m = (first+last)/2, n = last; int q = m + 1; mergesort(a,first,m,temp); mergesort(a,m+1,last,temp); while (p <= m ||q<= n) { if (p<=m && q<=n && a[p] <= a[q]) temp[i++] = a[p++]; if(p<=m && q<=n && a[p]>a[q]) { cur+=m+1-p; temp[i++] = a[q++]; } while (q>n && p<=m) temp[i++] = a[p++]; while(p >m &&q <=n) { temp[i++]=a[q++]; } } for (i = first; i <= n; i++) a[i] = temp[i]; } } int main() { int n,t,i,j; while(scanf("%d",&n)!=EOF&&n!=0) { for(i=0;i<n;i++) scanf("%d",&a[i]); mergesort(a,0,n-1,temp); /* for(i=0;i<n;i++) printf("%d ",a[i]); */ printf("%I64d\n",cur); cur=0; } return 0; }
超时代码:#include <iostream> #include<cstdio> using namespace std; #define M 500010 __int64 cur; int a[M],temp[M]; 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 <= mid && j <= last) { if (a[i] <= a[j]) temp[k++] = a[i++]; else { temp[k++] = a[j++]; cur+=mid+1-i; } } while (i <= mid) temp[k++] = a[i++]; while (j <= last) 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 n,t,i,j; while(scanf("%d",&n)!=EOF) { cur=0; for(i=0;i<n;i++) scanf("%d",&a[i]); for(i=0;i<n;i++) mergesort(a,0,n-1,temp); /* for(i=0;i<n;i++) printf("%d ",a[i]); */ printf("%I64d\n",cur); } return 0; }
题目描述:求冒泡排序的交换次数所用算法:用归并排序,求逆序数的个数提交情况:1次tle(直接冒泡排序n^2的复杂度,对于5000000的数据量,必然超时),1次wa(统计个数时整数溢出了),1a心得体会:初看题目很简单,没有往数据量方面想,直接冒泡计数提交,然后看着poj上一直running&&judging直到tle, 时限7000ms呀。没做过逆序数的类似问题,
而且题目本身分类也在排序那,然后考虑是不是能快排一下,比较排序前和排序后各个数的位置。考虑再三,发现解决不了。去论坛上瞄了一眼,看到可以用逆序数
解,于是百度+算法导论,学到了如何用归并排序计算逆序数的数目,写成程序,中间还出现了一次wa,然后就ac了。我在看算法导论时,因为merge在书一开始讲的
,想平时排序都是快排为主流,就没有仔细想过merge可能的变种,这道题充分印证了,即使merge本身可能用的不多,但分冶的思想却是无所不在
感觉两个都一样,只是一个用一个只用了一个函数,一个用了两个函数。
但是一个300+MS,一个超时。