在白书中提到了一种O(n)级别的寻找中位数算法 就是我们今天要介绍的主角

快速选择算法

类似快排 选择一个比较元素 进行递归处理寻找第k大元素

假设最后比较元素到了i

以下描述是我写快排的常用字符 所以外人应该看不懂。。。。

如果(i-s+1)<k  去(i+1,t)的区间  递归寻找第(k-(i-s+1)) 大的数

如果(i-s+1)=k 返还i的值即可

如果 (i-s+1)>k 去 (s,i-1)的区间 递归找第k大的数

类似快排的思想 很容易理解

代码如下:

int swap(long long &a,long long &b) {long long temp=a;a=b;b=temp;return 0;}
int quickchoice(long long *A,int s,int t,int k)
{
int i=s,j=t;
long long x=A[s];
while(i<j)
{
while(i<j&&A[j]>=x) j--;
if(i<j) swap(A[i],A[j]),i++;
while(i<j&&A[i]<x) i++;
if(i<j) swap(A[j],A[i]),j--;
}
A[i]=x;
if((i-s+1)==k) return 0;
else if((i-s+1)<k&&i+1<=t) quickchoice(A,i+1,t,k-(i-s+1));
else if((i-s+1)>k&&s<=i-1) quickchoice(A,s,i-1,k);
return 0;
}

UVA11300快速选择算法实现如下:

#include<cstdio>
#include<cmath>
#include<cstdlib>
using namespace std;
long long gold[1000100],M;
int cmp(const void *i,const void *j)
{
if(*(long long *)i>*(long long *)j) return 1;
else if(* (long long *)i==*(long long *)j) return 0;
else return -1;
}
int main()
{
int n,k;
long long sum;
while(scanf("%d",&n)!=EOF)
{
sum=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&gold[i]);
sum+=gold[i];
}
M=sum/n;
for(int i=1;i<=n-1;i++)
gold[i]=gold[i-1]+M-gold[i];
gold[n]=0;
qsort(gold+1,n,sizeof(gold[1]),cmp);
k=(n+1)/2;
sum=0;
for(int i=1;i<=n;i++)
sum=sum+abs(gold[i]-gold[k]);
printf("%lld\n",sum);
}
return 0;
}

上面这个方法不知道为何 速度和快排没什么区别。。

但是下面这个就快了一倍

nth_element函数 非常奇怪

好吧 觉得奇怪 是被网上各种奇葩的资料误导了

自己亲手操作后还是懂了

nth_element(begin,kth,end)

在[begin,end)这段区间内找第k大的数 其实这样描述是不精确的

这样描述似乎更合适

比如 nth_element(s+1,s+k,s+n+1)

在[1,n+1)这段区间内 s[k] 左边的全部小于等于他 右边的全部大于等于他

如果 区间从1开始 似乎确实可以描述成 第k个

如果不从1开始就注意点

AC代码如下:

#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;
long long gold[1000100],M;
int n;
int main()
{
int k;
long long sum;
while(scanf("%d",&n)!=EOF)
{
sum=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&gold[i]);
sum+=gold[i];
}
M=sum/n;
for(int i=1;i<=n-1;i++)
gold[i]=gold[i-1]+M-gold[i];
gold[n]=0;
k=(n+1)/2;
nth_element(gold+1,gold+k,gold+1+n);
for(int i=1;i<=n;i++)
printf("gold:%d\n",gold[i]);
sum=0;
for(int i=1;i<=n;i++)
sum=sum+abs(gold[i]-gold[k]);
printf("%lld\n",sum);
}
return 0;
}

【快速选择算法与nth_element函数】【续UVA11300 】的更多相关文章

  1. 选取第K大数的快速选择算法和注意事项

    快速选择算法,是一种能在大致O(N)的时间内选取数组中第k大或者k小的算法.其基本思路与快速排序算法类似,也是分治的思想. 其实这个算法是个基础算法,但是不常用,所以今天编的时候错了POJ2388,才 ...

  2. POJ 2388 Who's in the Middle (快速选择算法:O(N)求数列第K大)

    [题意]求数列中间项. ---这里可以扩展到数列第K项. 第一次做的时候直接排序水过了= =--这一次回头来学O(N)的快速选择算法. 快速选择算法基于快速排序的过程,每个阶段我们选择一个数为基准,并 ...

  3. 求一无序数组中第n大的数字 - 快速选择算法

    逛别人博客的时候,偶然看到这一算法题,顺便用C++实现了一下. 最朴素的解法就是先对数组进行排序,返回第n个数即可.. 下面代码中用的是快速选择算法(不晓得这名字对不对) #include <v ...

  4. nth_element函数

    使用方法:nth_element(start, start+n, end) 使第n大元素处于第n位置(从0开始,其位置是下标为n的元素),并且比这个元素小的元素都排在这个元素之前,比这个元素大的元素都 ...

  5. Java实现 蓝桥杯VIP 算法训练 sign函数

    试题 算法训练 sign函数 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定实数x,输出sign(x)的值. sign(x)是符号函数,如果x>0,则返回1:如果x=0, ...

  6. Java实现蓝桥杯VIP算法训练 二元函数

    试题 算法训练 二元函数 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 令二元函数f(x,y)=ax+by,a和b为整数,求一个表达式S的值. 只有满足以下要求的表达式才是合法的: ...

  7. KMP算法中next函数的理解

    首先要感谢http://blog.csdn.net/v_july_v/article/details/7041827以及http://blog.chinaunix.net/uid-27164517-i ...

  8. C++ STL算法系列6---copy函数

    现在我们来看看变易算法.所谓变易算法(Mutating algorithms)就是一组能够修改容器元素数据的模板函数,可进行序列数据的复制,变换等. 我们现在来看看第一个变易算法:元素复制算法copy ...

  9. C++ STL算法系列1---count函数

    一.count函数 algorithm头文件定义了一个count的函数,其功能类似于find.这个函数使用一对迭代器和一个值做参数,返回这个值出现次数的统计结果. 编写程序读取一系列int型数据,并将 ...

随机推荐

  1. HDU 4121 Xiangqi (算是模拟吧)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4121 题意:中国象棋对决,黑棋只有一个将,红棋有一个帅和不定个车 马 炮冰给定位置,这时当黑棋走,问你黑 ...

  2. 智能路由——ESB

    SOA之我见 SOA已然是企业级开发的必定之路.有人会问:我们有了OOP,还须要SOA吗?好吧我承认,这个问题也困扰了我非常久.现现在我得出的结论是:OOP是OOP,SOA是SOA. OOP是指面向对 ...

  3. Android内存泄漏监测(MAT)及解决办法

    http://ttlnews.blogspot.com/2010/01/attacking-memory-problems-on-android.html 这篇文章是2010年1月份写的,其中有些已经 ...

  4. CSS彻底研究(2)

    Github pages 博文 一 . CSS盒模型 1.盒子的结构 margin-border-padding结构 + 内容content 组成盒模型 注意 width,height 取的是cont ...

  5. T4运行时模板

    可以通过Visual Studio运行时文本模板在您的应用程序在运行时生成文本字符串. 执行应用程序的计算机不必具有 Visual Studio. 运行库模板有时称为"预处理文本模板&quo ...

  6. Content-Disposition的使用和注意事项(转载)

    Content-Disposition的使用和注意事项 最近不少Web技术圈内的朋友在讨论协议方面的事情,有的说web开发者应该熟悉web相 关的协议,有的则说不用很了解.个人认为这要分层次来看待这个 ...

  7. 使用 Require.js 引用第三方框架时遇到的一些情况

    使用 Require.js 引用第三方框架时遇到的一些情况 在使用Require.js解析依赖的时候,会出现以下几种情况: 程序中的依赖关系 当前程序 依赖于 B包, B包 依赖于 A包 A包与B包两 ...

  8. git的使用与积累

    之前对git可以说是一无所知,不过现在做工程要用到,于是就花点时间找了一些资料,本文也只是各种git学习资料的集合,权当是学习笔记吧 一:git的安装与配置 首先,git其实一般在linux环境下都是 ...

  9. windows在文件夹快速打开命令行

    普通打开方式 按住shift键,在指定的文件夹上右键,会发现有"在此处打开命令行窗口"的字样,选择该项,即可打开命令行,并且路径刚好是你刚才选择的文件夹路径 管理员方式打开 修改注 ...

  10. Yogurt factory(POJ 2393 贪心 or DP)

    Yogurt factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8205   Accepted: 4197 De ...