80pts求助,第一个数据出现了tle,(应该是死循环

P1923 【深基9.例4】求第 k 小的数

Bug_maker @ 2021-01-13 10:46:14

#include <bits/stdc++.h>

int a[5000005];
int n, k;

int mid(int arr[], int i1, int i2, int i3){
    if(arr[i1] > arr[i2])
        i2 = i1;
    if(arr[i2] > arr[i3])
        i2 = i3;
    return i2;
}

void swap(int &a, int &b){
    int temp = a;
    a = b;
    b = temp;
}

int pivot(int arr[], int lo, int hi){   //[lo, hi)
    //[0, lo) 小于等于pivot
    //[hi, n) 大于等于pivot
    int mi = (lo + hi) >> 1;
    int pr = mid(arr, lo, mi, hi-1);    //pivotRank
    swap(arr[lo], arr[pr]);
    int pivot = arr[lo];
    while(hi > lo){
        while(lo < hi){
            if(hi >= n || arr[hi] > pivot)
                hi--;
            else{
                arr[lo++] = arr[hi];
                break;          
            }
        }
        while(lo < hi){
            if(arr[lo] < pivot)
                lo++;
            else{
                arr[hi--] = arr[lo];
                break;
            }
        }
    }
    arr[lo] =  pivot;
    return lo;
}

void solve(int arr[], int lo, int hi, int k){
    //printf("%d %d\n", lo, hi);
    int x = 0;
    while(k != (x = pivot(arr, lo, hi))){
        if(x < k)
            lo = x+1;
        else
            hi = x;
    }
    printf("%d\n", arr[x]);
}
// void sort(int arr[], int lo, int hi){
//  // printf("%d %d\n", lo, hi);
//  // for(int i = 0; i < n; i++)
//  //  printf("%d ", a[i]);
//  // printf("\n");
//  int k = pivot(arr, lo, hi);
//  // for(int i = 0; i < n; i++)
//  //  printf("%d ", a[i]);
//  // printf("\n");
//  if(k - lo > 1)
//      sort(arr, lo, k);
//  if(hi - k - 1 > 1)
//      sort(arr, k+1, hi);
// }

int main(void){
//  FILE * fp = fopen("in.txt", "r");
    scanf("%d %d", &n, &k);
//  fscanf(fp, "%d %d", &n, &k);
    for(int i = 0; i < n; i++){
        scanf("%d", a+i);
//      fscanf(fp, "%d", a+i);
    }
    solve(a, 0, n, k);
    //sort(a, 0, n);
    // for(int i = 0; i < n; i++)
    //  printf("%d ", a[i]);
}

代码如上,用了同样pivot函数的快排吸个氧气就ac了。但是这段代码却出现了一个tle。


by Bug_maker @ 2021-01-13 11:25:14

明白哪里出错了,如果考虑单元素的话数组的话,我这段代码返回lo+1而不是lo。

在进入循环之前将hi--,可解决此问题。

若按此实现,需将注释改为 [lo, lo')小于等于pivot,(hi', hi)大于等于pivot


|