【输入样例】
10
20 40 32 67 40 20 89 300 400 15
提示:桶排
(桶排序是要下标数不大,开数组可以开得到的情况下,才可以)
1、桶排序的复杂度是值域相关的。当值域很大并且分布不均匀时,桶排序需要增加轮数,效率随之降低。
2、桶排序不是比较排序,对于一些需要比较才能完成排序的问题(如精确的分数比较),桶排序就不能实现。
以后扩展,桶排序可以用离散化来应用。下面是一段例子
参考资料: https://www.luogu.com.cn/problemnew/solution/P1908
//优化:离散化,因为n<=40000,所以只需要存那个数在数组中是第几大就好了。(然而并没有什么用)离散代码片段:
bool cmp1(const int &x,const int &y)
{
return b[x]>b[y]; //对编号进行排序
}
int main()
{
int ans=0;
scanf("%d",&n);
for(register int i=1;i<=n;i++)
{
scanf("%d",&b[i]); //读入
a[i]=i;//顺便初始化一下
}
sort(a+1,a+n+1,cmp1); //排序
//这里略过接下来的部分,a[]就是我们要用的"第几大"数组
}
离散化的例子二:
离散化(李三花)
小蓝居然可以把离散化读成那个,我觉得它非常的厉害!!!!!
话不多说,开始我们的离散化吧!其实大家完全没有必要去看网上那些东西,特别是百度百科,简直有毒,我们现在还用不到那么牛逼的离散化,所以这里介绍的离散化是非常简单的一种。
所谓离散化,就是说你发现了这个逆序对这道题啊,非常的讨厌,数据这么大,那么我们可不可以适当的把数据范围缩小一点呢?其实是可以的,我们发现,逆序对这道题有一个特点,就是比如说数据2 1还是数据 203903123 1它都是一个逆序对,前面的数都是比1大,但是我们不用管他比1大多少,只要比1大就可以了,但是为我们可以明显感觉到我们要对后面的数据处理一下,否则就要开爆树,在这里我们只需要把它处理成2就可以达到相同的效果。
举例一下:
2 33423434 437834 25345 373 35 //就可以被换成
1 6 5 4 3 2 //效果一样
但是你可能会说哎呦,我还排个序,编个号,那个时候我怎么知道原来它是什么样子的啊?
结构体大法好!!!
离散化基本操作如下:
#include<bits/stdc++.h>
using namespace std;
struct sd{
int val,loc;//val是值 loc是当前点的位置
}x[100005];
bool cmp(sd a,sd b)
{
if(a.val<b.val)
return true;
}
int discretization[100005];//这单词真够长
int main()
{
std::ios::sync_with_stdio(false);
int n;
cin>>n;
for(int i=1;i<=n;++i)
{
cin>>x[i].val;
x[i].loc=i;
}
sort(x+1,x+n+1,cmp);
int cnt=0;
x[0].val=891881292;//important!
for(int i=1;i<=n;++i)
{
if(x[i-1].val==x[i].val)discretization[x[i].loc]=cnt;
else
{
cnt++;
discretization[x[i].loc]=cnt;
}
}
for(int i=1;i<=n;++i)
{
cout<<discretization[i]<<" ";
}
return 0;
}