思路:固定一个数,把这个数放到合法的位置,然后左边的数都是比它小,右边的数都是比它大

固定权值选的是第一个数,或者一个随机数

因为固定的是左端点,所以一开始需要在右端点开始,找一个小于权值的数,从左端点开始,找一个大于权值的数

那么交换他们即可、最后的话,One == two那个位置就是权值应该去到的位置,这个时候把原问题划分为更小的子问题

就是[be, one - 1]和[one + 1, en]这两个子问题。

下面的是有bug的,当rand去到en的时候,就会wa  (修复了)

比如数据是,4、5、1、2就很容易wa

用随机做了一个TLE了,还没wa就TLE了

http://codeforces.com/contest/732/problem/D

ID = be也是TLE,不明白STL的sort是怎么来的

int myRand(int be, int en) {
return be + (rand() % (en - be + ));
} void quickSort(int a[], int be, int en) {
if (be >= en) return ;
int id = myRand(be, en); // 这样不行,需要id = be
int one = be, two = en;
while (one != two) {
while (two > one && a[two] >= a[id]) --two; // 找第一个比id小的, 必须先找小的
while (one < two && a[one] <= a[id]) ++one; // 找第一个比id大的, 因为基准数是be
if (one < two) swap(a[one], a[two]);
//固定id = be,需要从右到左是因为,如果是从左到右,例子1、2、3、4、5
//找到第一个比1大的,是2,然后找不到第一个比1小,在2中相遇
//然后swap(a[1], a[2]) GG
}
swap(a[id], a[one]);
quickSort(a, be, one - );
quickSort(a, one + , en);
}

修复:

随机一个id,然后和第一那个数交换,就可以了。和id = be一样了

int myRand(int be, int en) {
return be + (rand() % (en - be + ));
} void quickSort(int a[], int be, int en) {
if (be >= en) return ;
int id = myRand(be, en); //
swap(a[be], a[id]);
id = be;
int one = be, two = en;
while (one != two) {
while (two > one && a[two] >= a[id]) --two; // 找第一个比id小的, 必须先找小的
while (one < two && a[one] <= a[id]) ++one; // 找第一个比id大的, 因为基准数是be
if (one < two) swap(a[one], a[two]);
//固定id = be,需要从右到左是因为,如果是从左到右,例子1、2、3、4、5
//找到第一个比1大的,是2,然后找不到第一个比1小,在2中相遇
//然后swap(a[1], a[2]) GG
}
swap(a[id], a[one]);
quickSort(a, be, one - );
quickSort(a, one + , en);
}

随机生成区间里的一个数字思路:

区间大小是len,那么就生成一个0---len-1的数,加上起始点,就是落在[be, en]的数

代码在上面。

O(n)找第k小的数

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = 1e5 + ;
int myRand(int be, int en) {
return be + (rand() % (en - be + ));
}
int findKthMin(int a[], int be, int en, int k) {
if (be == en) return a[be];
swap(a[be], a[myRand(be, en)]);
int one = be, two = en, id = be;
while (one != two) {
while (two > one && a[two] >= a[id]) --two; // 找第一个比id小的, 必须先找小的
while (one < two && a[one] <= a[id]) ++one; // 找第一个比id大的, 因为基准数是be
if (one < two) swap(a[one], a[two]);
//需要从右到左是因为,如果是从左到右,例子1、2、3、4、5
//找到第一个比1大的,是2,然后找不到第一个比1小,在2中相遇
//然后swap(a[1], a[2]) GG }
swap(a[id], a[one]);
int hasKey = one - be + ; // 有多少个元素
if (hasKey >= k) return findKthMin(a, be, one, k);
else return findKthMin(a, one + , en, k - hasKey);
}
int a[maxn];
void work() {
int n;
scanf("%d", &n);
for (int i = ; i <= n; ++i) {
scanf("%d", a + i);
}
printf("%d\n", findKthMin(a, , n, ));
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}

最热门K串

找前k大的数,首先找到第n - k + 1小的数,那么这些数的右边,都是比它大的,这个时候就是前k大了,直接排序一下就好

#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = + ;
int myRand(int be, int en) {
return be + (rand() % (en - be + ));
}
int findKthMin(int a[], int be, int en, int k) {
if (be == en) return be;
swap(a[be], a[myRand(be, en)]);
int one = be, two = en, id = be;
while (one != two) {
while (two > one && a[two] >= a[id]) --two; // 找第一个比id小的, 必须先找小的
while (one < two && a[one] <= a[id]) ++one; // 找第一个比id大的, 因为基准数是be
if (one < two) swap(a[one], a[two]);
//需要从右到左是因为,如果是从左到右,例子1、2、3、4、5
//找到第一个比1大的,是2,然后找不到第一个比1小,在2中相遇
//然后swap(a[1], a[2]) GG }
swap(a[id], a[one]);
int hasKey = one - be + ; // 有多少个元素
if (hasKey >= k) return findKthMin(a, be, one, k);
else return findKthMin(a, one + , en, k - hasKey);
}
int a[maxn];
void work() {
int n, k;
scanf("%d%d", &n, &k);
for (int i = ; i <= n; ++i) {
scanf("%d", a + i);
}
int id = findKthMin(a, , n, n - k + );
sort(a + id, a + + n);
for (int i = n; i >= id; --i) {
printf("%d ", a[i]);
}
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}

快速排序算法的实现 && 随机生成区间里的数 && O(n)找第k小 && O(nlogk)找前k大的更多相关文章

  1. C语言实现随机生成0~100的数

    #include <iostream> #include <time.h> int main() { srand((unsigned)time(NULL));//srand() ...

  2. 基于 MPI 的快速排序算法的实现

    完整代码: #include <iostream> #include <cstdlib> #include <ctime> #include <algorit ...

  3. C++基础代码--20余种数据结构和算法的实现

    C++基础代码--20余种数据结构和算法的实现 过年了,闲来无事,翻阅起以前写的代码,无意间找到了大学时写的一套C++工具集,主要是关于数据结构和算法.以及语言层面的工具类.过去好几年了,现在几乎已经 ...

  4. 【bzoj3065】: 带插入区间K小值 详解——替罪羊套函数式线段树

    不得不说,做过最爽的树套树———— 由于有了区间操作,我们很容易把区间看成一棵平衡树,对他进行插入,那么外面一层就是平衡树了,这就与我们之前所见到的不同了.我们之前所见到的大多数是线段树套平衡树而此题 ...

  5. Python八大算法的实现,插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序。

    Python八大算法的实现,插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得 ...

  6. (转)DES、RSA、MD5、SHA、随机生成加密与解密

    一.数据加密/编码算法列表   常见用于保证安全的加密或编码算法如下:   1.常用密钥算法   密钥算法用来对敏感数据.摘要.签名等信息进行加密,常用的密钥算法包括:   DES(Data Encr ...

  7. 随机生成&部门匹配

    整体概况 1.完整程序概况 (1)程序整体构架 (2)生成程序模型 (3)匹配算法模型 (4)生成结果评估 (5)命名规范 (6)先期和后期分工 2.心路历程与对全新的java认识(心得体会篇) (1 ...

  8. 结对作业——随机生成四则运算(Core 第7组)

    结对作业 ——随机生成四则运算(core第7组) 吕佳玲 PB16060145 涂涵越 PB16060282 GITHUB地址 https://github.com/hytu99/homework_2 ...

  9. selenium + python自动化测试unittest框架学习(七)随机生成姓名

    在自动化测试过程中经常要测试到添加用户的操作,每次都要输入中文,原本是找了十几个中文写成了列表,然后从列表中随机取出填入用户名文本框中,随着测试的增加,发现同名的人搜索出来一大堆,最后在网上找了个随机 ...

随机推荐

  1. clone方法详解

    http://blog.csdn.net/zhangjg_blog/article/details/18369201/

  2. [学习笔记]通过open函数改变标准输出的方法

    int main(void) { char s[] = "abc.txt"; ; close(STDOUT_FILENO);//关闭标准输出文件描述符 int fd1 = open ...

  3. [转]VisualSVN错误 Cannot query proxy blanket解决办法

    最近重新做了一下系统,在安装和使用svn过程中遇到了一些问题,记下备忘. 第一次安装好系统之后,安装VisualSVN遇到报错: Custom action InstallWMISchemaExcut ...

  4. <a>实现按钮的javascript+jquery编程实例

    涉及知识点:怎样实现让注册的function获取当前<a>,以便通过它进行其他操作 风格一: 1.html端: <td class="text-center"&g ...

  5. Html5代码片段收集

    HTML5 启动模板 当启动一个新的项目的时候,你需要一个启动模板.这里是一个简洁干净的模板,可以作为 HTML5 项目的基础. <!DOCTYPE html> <html> ...

  6. 原子变量与CAS算法小结

    CAS算法 CAS(compare-and-swap)是一种硬件对并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令,用于管理对共享数据的并发访问. CAS是一种无锁非阻塞算法的实现. CAS ...

  7. Metasploit 读书笔记-持久控制

    Meterpreter的persisitence脚本允许主任meterpreter代理,以确保系统重启之后Meterpreter还能运行。如果是反弹连接方式,可以设置连接攻击机的时间间隔。如果是绑定方 ...

  8. 正经学C#_循环[do while,while,for]:[c#入门经典]

    在c#中循环语句总共三种,do...while ,while,for这三种语句. 循环语句,是为了解决一些繁琐的计算.比如输出0-10这10个数字. 在不循环的情况下你可以能这么写 Console.W ...

  9. Hadoop的安装与配置

    一.准备环境: 系统:centos6.5 64位 192.168.1.61   master 192.168.1.5     slave 二.在两台服务器上都要配置ssh免密码登录 在192.168. ...

  10. Python3中开发目录的引用

    Python3中开发目录的引用 import os,sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) ...