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

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

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

那么交换他们即可、最后的话,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. 具有增删改查功能的表格Demo--【BootStrap】

    http://blog.csdn.net/wangmei4968/article/details/48437175

  2. [OpenGL]点阵显示生日快乐小程序

    刚工作没多久的时候,业余学习了OGL的知识(这是写不好的借口吧), 在某个异性生日的时候写了这个程序. 编译平台: MinGW GCC gcc -o happOK happyOK.c -lglut32 ...

  3. Python3 中hashlib及uuid的用法

    Python3 中hashlib及uuid的用法: 可以生成随机ID import uuid import hashlib import time def creat_uuid(): return s ...

  4. springboot jpa mongodb 整合mysql Field in required a bean of type that could not be found Failed to load ApplicationContext

    1.完整报错 *************************** APPLICATION FAILED TO START *************************** Descripti ...

  5. 网络通讯与IP地址

    1.主机:Host,台式机,笔记本,手机等设备 2.网络介质:网线,光纤,无线网Wi-Fi.移动网络 3.数据:一串子节 网络通讯的检测:安装wireshark,通常称为抓包工具 抓,capture ...

  6. [USACO08FEB]酒店Hotel 线段树 BZOJ 1593

    题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a ...

  7. 【模板】缩点 tarjan+dp

    题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只 ...

  8. 勤哲Excel服务器人力资源管理系统

    “一个和尚挑水吃,两个和尚抬水吃,三个和尚没水吃!”,这则古老寓言之于现代企业管理而言,相当有意义.在现代企业管理中,类似三个和尚没水吃的管理难题是普遍存在的.如何有效破解?还是得从管理下手,从建立管 ...

  9. HDU - 6416 :Rikka with Seam(DP & 前缀和 & 数学)

    pro:给定N*M的矩阵,现在让你在每一行删去一个位置,然后形成新N*(M-1)的矩阵,问有多少种不同的新的矩阵.需要满足相邻行删去的位置不大于K. (题目是01矩阵,其实任意矩阵都可以做,本题算法里 ...

  10. Android----获取包名和sh1

    第一种:使用java的一个工具---keytool工具(jdk目录下) SHA1叫安全哈希算法用于签名 keytool -list -v -keystore 签名证书所在位置path 第二种:通过An ...