ACdream OJ 1099 瑶瑶的第K大 --分治+IO优化 - whatbeg

来源:互联网 发布:分布式节点共识算法 编辑:程序博客网 时间:2024/04/29 18:46

ACdream OJ 1099 瑶瑶的第K大 --分治+IO优化 - whatbeg

顺便把求数组中第K大数和求数组中第K小数的求法给出来。

代码:

/** this code is made by whatbeg* Problem: 1099* Verdict: Accepted* Submission Date: 2014-06-15 00:13:53* Time: 4340 MS* Memory: 21212 KB*/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <cstdlib>#include <iomanip>using namespace std;#define N 1007//复杂度O(n)int Max_K(int a[],int low,int high,int k){  if(k <= 0 || k > high-low+1)    return -1;  int flag = low + abs(rand())%(high-low+1);  //随机选择一个基准点  swap(a[low],a[flag]);  int mid = low;  int cnt = 1;  for(int i=low+1;i<=high;i++)  {    if(a[i] > a[low])   //遍历,把较大的数放在数组左边    {      swap(a[++mid],a[i]);      cnt++;    }  }  //比基准点大的数的个数为cnt-1  swap(a[mid],a[low]);//将基准点放在左、右两部分的分界处  if(cnt > k)    return Max_K(a,low,mid-1,k);  else if(cnt < k)    return Max_K(a,mid+1,high,k-cnt);  else    return mid;} int Min_K(int a[],int low,int high,int k){  if(k <= 0 || k > high-low+1)    return -1;  int flag = low + abs(rand())%(high-low+1);  swap(a[low],a[flag]);  int mid = low;  int cnt = 1;  for(int i=low+1;i<=high;i++)  {    if(a[i] < a[low])    {      swap(a[++mid],a[i]);      cnt++;    }  }  swap(a[mid],a[low]);  if(k < cnt)    return Min_K(a,low,mid-1,k);  else if(k > cnt)    return Min_K(a,mid+1,high,k);  else    return mid;} inline int in(){  char ch;  int a = 0;  while((ch = getchar()) == ' ' || ch == '\n');  a += ch - '0';  while((ch = getchar()) != ' ' && ch != '\n')  {    a *= 10;    a += ch - '0';  }  return a;} inline void out(int a){  if(a >= 10)    out(a / 10);  putchar(a % 10 + '0');} int a[5000006]; int main(){  int n,k;  while(scanf("%d%d",&n,&k)!=EOF)  {    getchar();    for(int i=0;i<n;i++)      a[i] = in();    int res = Max_K(a,0,n-1,k);    out(a[res]);    puts("");  }  return 0;}
0 0