在白书中提到了一种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. ASP.NET内核几大对象、ASP.NET核心知识(7)--转载

    本文的学习流程是这样安排的. 一个简单的GDI小案例 1.说明 如果你想思考如何生成验证码,那么您第一个要解决的问题,一定是.NET动态生成图片问题. //GDI:.Net程序中进行绘图的一些类. 2 ...

  2. 要将程序集“xxx.dll”标记为系统必备组件,必须对其进行强签名

    最近编译经常偶尔出现标题这个错误,有时重启电脑,就正常了,有时重启也不行,真蛋疼,后来发现把dll预先拷贝到生成目录,也可以避免这个编译错误,但是实在是麻烦,再去Google了半天,终于找到了解决方案 ...

  3. 1207.1——C语言 函数

    函数可以分为无参函数和有参函数. 无参函数的定义 无参函数定义的一般形式如下:返回值类型  函数名(){    函数体} 说明: 返回值类型可以是C语言中的任意数据类型. 函数名是标识符的一种,命名规 ...

  4. DataGridView常用功能

    最近做Winform开发,DataGridView是必不可少的控件.整理了一下用到的基本功能的设置 1.情景1:当GridView的列没有自动填充,会出现一片空白的地方,特别不美观. 设置 自动填充G ...

  5. 006 列表的三种删除方法 remove,pop,del

    先定义一个列表: number=[,'changhao','常浩',5.2] . remove(): number.remove('changhao')---括号内是要删除的单一值 . pop(): ...

  6. (原+转)C++中的lambda表达式

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5073376.html 参考网址: http://www.cnblogs.com/zhuyp1015/a ...

  7. C# 操作系统回收站

    主要目的:对系统回收站的文件进行操作. 首先添加引用,引入shell32.dll. /// <summary> /// 对回收站的文件进行还原.删除.剪切等操作 /// </summ ...

  8. 关于《Cocos2d-x建工程时避免copy文件夹和库》的更新

    在前几篇博文中大概了解了Cocos2d-x引擎的基本结构后打算开始实际操作,便在网上转载了一篇关于VS新建Cocos2d-x项目的文章.今天实际操作的时候发现博主使用的引擎版本和我的不一致(<C ...

  9. 【转】nginx之主配置文件:root和alias

    nginx指定文件路径有两种方式root和alias,这两者的用法区别,使用方法总结了下,方便大家在应用过程中,快速响应.root与alias主要区别在于nginx如何解释location后面的uri ...

  10. Eclipse工程乱码解决

    eclipse之所以会出现乱码问题是因为eclipse编辑器选择的编码规则是可变的.一般默认都是UTF-8或者GBK,当从外部导入的一个工程时,如果该工程的编码方式与eclipse中设置的编码方式不同 ...