浅谈优化排序的1种思路

浅谈优化排序的一种方法及排序的思维

S O R T , s s u p e r o o i e r r r a c e r t t e e n e r


文章开头皮一下,增加点气氛,现在开始入正题,qwq

- 在这儿,所以排序默认为从小到大。

  • 1. 排序有很多种,如希尔,归并,快速,甚至是noi入门作弊系统sort,我是不会提到dev的任何作弊函数

  • https://baike.so.com/doc/1008529-1066354.html

  • https://baike.so.com/doc/4608506-4820714.html
    在此就不一一举例了qwq
  • 2.排序有风险,谨记!!!

    快排很快,虽然稳定性不如暴力枚举,但在一些知名oj上,一般遵循选排<冒泡<快排或是桶排<希尔<归并这两大原则,但是每个排序都会有不足,就算是sort作弊法,谨慎排序,才可以AK市赛

3. 排序能否优化?

谁都想优化排序,面对复杂度为Ons(log(2^n))的排序,到底怎么优化,我最近的新思路可以参考参考。
排序有3要素:数据繁多,数字太大,无法比较,至于第3要素,还是要等本蒟蒻进阶成为萌新时再另当别论吧
NO.1,数据繁多AK方案
- 第一种方案a方案是祈祷数据,祈祷noi赛时数据越少,或者F4审查元素,作弊,调试程序”%0|%0”,靠这种方法,好评%0 差评%100 失败率%100

  • 第二种方案b方案是暴力排序,是本蒟蒻的妙计,哪怕你什么排序都不会,如果会拓扑排序,那就调试一下程序,保证 A C ,但是不会拓扑排序,1基础的话那就看看题目空间限制,如果n<=50,那就用暴力枚举骗分法,int a[51]={0,0,…(50个数都赋值为0)}然后就每两个数判断一次,比如说输入10个数,那另外40个数全部为0,但是继续排序,例如先判断第一个数a与第二个数b谁大,如果a大就跟b交换位置,再让b跟c判断,把a从j都排个遍算一轮的话,再排个50轮,能骗个10分。好评%2 差评%95 失败率%96

  • 第三种方案c方案 初级去重,首先先去重这个序列,再将去重的数统计次数,比如说针对序列3 32 43 1213 11 11 可以改成3 32 43 1213 11(2),说明有2个11,输出的时候多输出几个11就可以了,其实它就是桶排序,但是进行了超级优化,桶排序是将去重和排序合2为1,而且效果很差。我是针对输入的数组a再弄一个n那么大的数组b,b默认每个值为1,每去重一次,那个数的所在b的位置为0,另外一个数的所在b的位置++,代码暂时不贴,这种方案的解释花了我的所有脑细胞,具体这个初级去重就是this思路,对了,还有一点就是最好用插入排序qwq qwq qwq好评%50 差评%66 失败率%60

  • 第四种方案d方案is中级去重,this方法有点不适应我这种膜拜陆神的蒟蒻了,开门见山,我就直说吧!!!它把初级去重修改了一下,针对序列333 33 3 33 98 56,先是改成333 33(2) 3 98 56,再看一下第一个数333,他比98要大,但是333就在98后面,因此直接将98与333合成一个序列,其实就是归并排序的思路,其他,再是98&333,3&33(2),56,再合成就可以了,但这个合成要用quickly sort。好评%55 差评%70 失败率%59

  • 第五种方案e方案is高级去重,这已经很难了。好!他把中级去重又修改了一下,而且效果及佳。比如说序列12 89 87 34 12 34先成为12(2),89,87,34(2),再看
    12(2)-89=-77,89-87=2,87-34(2)=53,34(2)-12(2)=22,12与34较接近,因此并成12(2)&34(2),而89和87的差最小,因此可以并成89&87,也就是说,只要排序排到了87,下一个就一定是89,而12(2)与89相差太大,可以证明一个在前一个在最后,这个去重只要找到最大数与最小数,就不需要排序了,因为他们是紧紧相连的,如12后面必定是34。好评%56 差评%99 失败率%50

关于数据繁多AK方案,因为篇幅有限,就写到这里

NO.1,数字太大AC方案
- 第一种f方案不用说了,祈祷F4
- 第二种g方案其实也不用说了,首先找规律,能否用各种歪门邪道的方法来优化数字,类似b,c方案,暴力优化,暴力出奇迹。
- 第三种h方案是一个非常作弊的方案,按理来说,输入序列12 12 12 32 12 12,你在输入的时候输入12时,将他直接默认为0,后面依次减12,就成了0,0,0,20,0,0,借鉴一下g方案和c方案再去重一下,排序一次,ok,保证10分及以下.
- 第4种方案真的是666,不信你看,首先认识一个神犇盘踞的.com,酷町堂和酷町问答!!!http://judge.codingtang.com/ http://wenda.codingtang.com/,然后再看酷町堂的一个问题2781
- 2781 发糖果

扫描二维码关注公众号,回复: 2980486 查看本文章

题目描述 Description
在参加了一场游戏后,每个小朋友都得到了不错的分数,现在他们排成一排等着发糖果。每个小朋友至少发一颗糖。如果一个小朋友比左边或者右边的小朋友得分高,则他得到的糖果应该比左边或者右边的要多。请计算在满足条件的情况下最少要发多少个糖果。

输入描述 Input Description
第一行,一个整数,n
接下来一行,n整数,s1 s2 … si … sn,表示这一排中第i个小朋友的分数是si

输出描述 Output Description
输出最少需要多少个糖果

样例输入 Sample Input
3
1 2 1

样例输出 Sample Output
4

数据范围及提示 Data Size & Hint
n≤100
这道题是贪心的,看懂它的意思没?
所以,我们来做个模拟。
输入12999999 77382372 89898989 12999999 -10000怎么办!!!
没事可以直接优化成2 3 4 2 1的排序,就是这么简单。
待会贴代码
//简易排序
//输入
//将所有值单位变成1,2781的思路
//如果ai=aj,ai.c++,如果哪两个值一样,去重,统计
//排序

//简易排序
//输入
//将所有值单位变成1,2781的思路
//如果ai=aj,ai.c++,如果哪两个值一样,去重,统计
//排序
#include<bits/stdc++.h>
using namespace std;
int a[10000]/*得分*/,b[10000]/*糖果*/,c[10000]/*数量*/;
int main()
{
    for(int i=0;i<10000;i++)c[i]=1;
    //qwq//qwq//qwq
    int n,m,k;
    cin>>n;
    for(int i=0;i<n;i++)cin>>a[i];
    for(int i=1;i<n;i++)
    {
        if(a[i]>a[i-1])
            b[i]=b[i-1]+1;
        else b[i]=1;
    }
    for(int i=n-2;i>=0;i--)
    {
        if(b[i]<=b[i+1]&&a[i]>a[i+1])
            b[i]=b[i+1]+1;
    }
    for(int i=0;i<n-1;i++)
    {
        if(a[i]==a[i+1])c[i]++; 
    }
    for(i=n-1;i>=1;i--)
    {
        for(j=0;j<i;j++)
        {
            if(b[j]>b[j+1])
            {
                swap(b[j],b[j+1]);
                swap(a[j],a[j+1]);
            }
        }
    }
    for(int i=0;i<n;i++)
    {
        while(c[i]--)cout<<a[i]<<" ";
    }
    return 0;
} 

后面有很多方案,一言难尽。

我的思想仅供大家参考,请认准商标。

这里写图片描述
发贴者:酷町堂最菜蒟蒻,没有之一。

猜你喜欢

转载自blog.csdn.net/qq_43062741/article/details/82085112