30 #10771. 分治算法(NOIP2008)找第k大的数

分治算法(NOIP2008)找第k大的数

(NOIP2008)找第k大的数

给定一个长度为1000000的无序正整数序列,以及另一个数n(1<=n<=1000000),接下来以类似快速排序的方法找到序列中第n大的数(关于第n大的数:例如序列{1,2,3,4,5,6}中第3大的数是4)。

#include<iostream>
using namespace std;
int a[1000001], n, ans=-1;
void swap(int &a, int &b) {
    int c;
    c=a; a=b; b=c;
}

int FindKth(int left, int right, int n) {
    int tmp, value, i, j;
    if(left==right) return left;
    tmp=rand()%(right-left)+left;
    swap(a[tmp],a[left]);
    value=①;
    i=left;
    j=right;
    while(i<j) {
        while(i<j&&②)j--;
        if(i<j){a[i]=a[j];i++;} else break;
        while(i<j&&③)i++;
        if(i<j){a[j]=a[i];j--;} else break;
    }
    ④;
    if(i<n) return FindKth(⑤);
    if(i>n) return ⑥;
    return i;
}

int main() {
    int i;
    int m=1000000;
    for(i=1;i<=m;i++)
        cin>>a[i];
    cin>>n;
    ans=FindKth(1,m,n);
    cout<<a[ans];
    return 0;
}

①处应填( )。
{{ select(1) }}

  • a[left]
  • a[tmp]
  • a[right]
  • a[n]

②处应填( )。
{{ select(2) }}

  • a[j]<value
  • a[j]>value
  • a[j]<a[i]
  • a[j]>a[i]

③处应填( )。
{{ select(3) }}

  • a[i]<value
  • a[i]>value
  • a[i]<a[j]
  • a[i]>a[j]

④处应填( )。
{{ select(4) }}

  • a[i]=a[left]
  • a[i]=a[right]
  • a[i]=a[tmp]
  • a[i]=value

⑤处应填( )。
{{ select(5) }}

  • i,right,n
  • i+1,m,n
  • i+1,right,n
  • i,m,n

⑥处应填( )。
{{ select(6) }}

  • FindKth(1,i-1,n)
  • FindKth(left,i-1,n)
  • FindKth(1,i,n)
  • FindKth(left,i,n)