桶排序,算法简单,逻辑简单,时间快,空间大!
先看个例题:就明白了
题目:要登记买书的同学,人数小于100,每个人报一个ISBN码,范围在1~1000;去掉重复的,
并将ISBN码从小大排列
1、桶排序,时间复杂的都为O(n+m),占空间大
```cpp
#include <stdio.h>
int main()
{
int arr[1001] = {0};
int n = 0;
int i = 0;
int t = 0;
int count = 0;
printf("请输入要登记买书的人数\n");
scanf("%d", &n);
for(i=1; i<=n; i++) //接受数据,并去重
{
scanf("%d", &t);
arr[t] = 1;
}
for(i=1; i<=1000; i++)
{
if(arr[i] == 1)
{
count++;
printf("%d ", i);
}
}
printf("\n共要买%d本书\n", count);
return 0;
}
桶排序就是,用题目给的数据范围做空间大小。
比如给的数据大小在0到1000,那么久定义a[1005],时间
复杂度是O(1000+m),m指的是重复数据的个数,可以忽略
来个高级例题
试题G:体前屈大赛 20'
描述
某校的火柴部部长拟定向筋肉部发起一场特别的活动:体前屈大赛
比赛流程是:公布规则->体前屈测试->颁发奖牌
比赛规则:初始参赛人员共有nn人,已知在体前屈测试后会有qq次特殊事件tt发生:
t=1t=1类事件:中途加入一名隐藏选手,已知他的体前屈成绩为kk;
t=2t=2类事件:将所有参赛人员根据体前屈成绩从左到右升序排序,并给从左到右数第kk个选手颁发倒霉奖
注:颁发了倒霉奖牌的选手仅仅是拥有奖牌,奖牌不会影响这位选手原来的性质与作用。
体前屈测试:在体前屈测试中初始参赛人员每人都会有一个体前屈成绩ai。
颁发奖牌:你是一名有一说一的纯路人裁判,颁发奖牌的任务降临到了你的头上
在你每一次颁发奖牌时,都要报出这位倒霉的选手的体前屈成绩!
请你利用你的计算机优势,编写一个程序, 根据已知条件输出每一次颁发奖牌时, 你需要报出的成绩。
输入
第一行输入22个整数n, qn,q;
第二行输入nn个整数a_i(- 1000≤a_i < 1000)a
i
(−1000≤a
i
<1000)
第3至(q+ 2)3至(q+2)行每行输入22个整数
t, k(1\le t\le 2,\begin{cases} -1000\le k \le 1000,t=1\\ 1\le k\le n, t = 2\end{cases})t,k(1≤t≤2,{
−1000≤k≤1000,t=1
1≤k≤n,t=2
)
能够保证至少有一个t = 2,即不会出现没有输出的情况。
输出
对于每个t = 2输出1个整数
样例
输入复制
5 8
-1000 1000 4 -5 0
2 1
2 2
2 3
2 4
2 5
1 -1000
2 1
2 2
输出复制
-1000
-5
0
4
1000
-1000
-1000
提示
数据规模
对于10\%10%的数据,1 \le n \le 10, 1\le q \le 101≤n≤10,1≤q≤10
对于40\%40%的数据,1 \le n \le 5000, 1\le q \le 2001≤n≤5000,1≤q≤200
对于100\%100%的数据,1 \le n \le 10^6, 1\le q \le 100001≤n≤10
6
,1≤q≤10000
```cpp
#include<iostream>
using namespace std;
int n,q;
int a[2005];
int qu[100000];
int main()
{
int flag=0;
cin>>n>>q;
for(int i=1;i<=n;i++)
{
int t;
cin>>t;
a[t+1000]++;
}
while(q--)
{
int x,y;
cin>>x>>y;
if(x==1)
{
a[1000+y]++;
}
else
{
int c=0;
for(int i=0;i<2005;i++)
{
int b=a[i];
c=c+a[i];
if(c>=y)
{
cout<<i-1000<<endl;
break;
}
}
}
}
return 0;
}