/********************** author: yomi date: 18.6.17 ps: 突然想到以序列合并代替快排,have a try! 这么想的原因是A1029 这种方法以O(n)的复杂度打败了我的快排O(nlogn) 然鹅,我忽视了一个问题,题目给的是递增序列,这是使用merge的前提条件。 我居然还以为我发现了又一排序算法。这么一想,归并不就用了merge。额,我真是天真的可以。 这么天真挺好的,至少我对归并和快排掌握得可以了。 **********************/ #include <iostream> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; int a[100010]; int temp[100010]; int Partition(int left, int right) { int p = round(1.0*rand()/RAND_MAX*(right-left)+left); swap(a[p], a[left]); int temp = a[left]; while(left < right){ while(left < right && a[right] > temp){ right--; } a[left] = a[right]; while(left < right && a[left] <= temp){///没写等号,竟然超时, left++;///测试了一下,是卡在循环里出不来了 }///理由很简单,因为有相等的 所以本函数中第一个while循环会一直满足条件 a[right] = a[left];///然后就卡在里面了 } a[left] = temp; return left; } void quicksort(int left, int right) { if(left <right){ int pos = Partition(left, right); quicksort(left, pos-1); quicksort(pos+1, right); } } void merge_(int l1, int r1, int l2, int r2) { int index = 0; int i=l1, j=l2; while(i<=r1 && j<=r2){ if(a[i] <= a[j]){ temp[index++] = a[i++]; } else{ temp[index++] = a[j++]; } } while(i<=r1){ temp[index++] = a[i++]; } while(j<=r2){ temp[index++] = a[j++]; } for(int i=0; i<index; i++){ a[l1+i] = temp[i]; } } int main() { int n; //cin >> n; scanf("%d", &n); for(int i=1; i<=n; i++){ //cin >> a[i]; scanf("%d", &a[i]); } quicksort(0, n-1); ///merge_(1, mid, mid+1, n); for(int i=1; i<=n-1; i++){ //cout << a[i] << endl; printf("%d ", a[i]); } printf("%d", a[n]); return 0; } /** 5 12 18 14 13 16 **/