一本通 1184:明明的随机数 1187:统计字符数 提示:桶排 (爸爸)

【输入样例】

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;
} 
发布了33 篇原创文章 · 获赞 0 · 访问量 167

猜你喜欢

转载自blog.csdn.net/weixin_42790071/article/details/105466522
今日推荐