不敢快速排序又想要快排的速度,还不用STL的小伙伴们看这里!

小金羊终于学会了堆排以外的另外的一种排序 (打个题解巩固一下)

归并排序(mergesort):

时间复杂度和快排一样的优秀。

先说归并排序的实现:

首先我们一样的是要进行分解,以达到\(O(logn)\)の时间复杂度。

然后我们需要了解一下它的思想:

如果两个序列的顺序已经排好,于是我们合并两个序列。

emmm...由于分解到最后只有一个元素,一定满足性质。

然后合并?玄学?这咋合并?

其实比较简单。

我们取两个指针,分别指向分解的序列的两个头部,然后比较指针指向的两个元素,满足的就放进我们的辅助空间,直到有一个序列已经用完。

所以如果剩下的序列如何处置?

刚刚说了,两个序列都是有序的,如果剩下的都不满足比原先的元素满足性质(大或者小,或者结构体之类的),那么剩下的就依次都放进去就好了。

没看懂?模拟一下。

首先序列w[10086],表示奶牛想等的时间,假设6头,序列情况如下:

(假设从小到大的顺序

//一开始
int w={6,2,3,4,5,1};
//分解第一次
w1={6,2,3},w2={4,5,1};
//分解第二次
w11={6}/*这个好了*/,w12={2,3},w21={4}/*这个也好了*/,w22={5,1};
//分解最后一次,已经分解完毕的不显示
w121={2},w122={3},w221={5},w222={1};
//所以现在序列是
w11={6},w121={2},w122={3},w21={4},w221={5},w222={1};
//接下来合并最后分解的那一拨
w11={6},w12_ok={2,3},w21={4},w22_ok={1/*来自w222*/,5};
//continue the merge
w1_ok={2,3,6/*比较到6剩下了,就放进来*/},;
w2_ok={1/*来自w22_ok*/,4/*来自w21*/,5/*from w22_ok*/};
//finally
w_ok={1/*from w2_ok*/,2/*from w1_ok...省略剩下的注释*/,3,4,5,6};

这就是归并排序的步骤。看看代码?

(仅仅是从小到大的mergesort样例模板代码)Code:

void mergesort(int l,int r)
{
if (l==r)return;//已经只剩一个元素
int mid=(l+r)>>1;//中部元素
mergesort(l,mid);//分解左边
mergesort(mid+1,r);//分解右边
int s2[r-l+1]/*辅助空间*/,p1=l,p2=mid+1,p3=1;
while (p1<=mid&&p2<=r)//没分解完
{
if (w[p1]<=w[p2])s2[p3++]=w[p1++];
else s2[p3++]=w[p2++];//以上两行是把较小的放进辅助空间
}
while (p1<=mid)s2[p3++]=w[p1++];//若有剩余,放进去
while (p2<=r)s2[p3++]=w[p2++];//若有剩余,放进去
p3=l;
for (register int i=1;i<=r-l+1;i++)
w[p3++]=s2[i];//再把排好的序列覆盖回去
}

看看这个题:

贪心策略:

先把最愿意排队的奶牛放前面,这样最不愿意排队的奶牛都吃草去了,保证队伍最小。

上代码:

#include <iostream>
#include <cstdio>
#include <cstring> using namespace std;
int w[100001],num,cnt=0;
void mergesort(int l,int r)
{
if (l==r)return;//已经只剩一个元素
int mid=(l+r)>>1;//中部元素
mergesort(l,mid);//分解左边
mergesort(mid+1,r);//分解右边
int s2[r-l+1]/*辅助空间*/,p1=l,p2=mid+1,p3=1;
while (p1<=mid&&p2<=r)//没分解完
{
if (w[p1]>=w[p2])s2[p3++]=w[p1++];
else s2[p3++]=w[p2++];//以上两行是把较小的放进辅助空间
}
while (p1<=mid)s2[p3++]=w[p1++];//若有剩余,放进去
while (p2<=r)s2[p3++]=w[p2++];//若有剩余,放进去
p3=l;
for (register int i=1;i<=r-l+1;i++)
w[p3++]=s2[i];//再把排好的序列覆盖回去
}
int main()
{
scanf("%d",&num);
for (register int i=1;i<=num;i++)
scanf("%d",&w[i]);
mergesort(1,num);
for (register int i=1;i<=num;i++)
{
if (w[i]<cnt)break;
cnt++;
}
printf("%d",cnt);
return 0;
}

最后提醒大家一点:

归并排序的辅助空间需求特别大,如是特别要求或者数据范围特别大,请小心使用。

题解 P4379 【[USACO18OPEN]Lemonade Line】的更多相关文章

  1. 洛谷 P4379 [USACO18OPEN]Lemonade Line

    P4379 [USACO18OPEN]Lemonade Line 题目描述 这是农场上一个炎热的夏日,Farmer John要给他的 NN 头奶牛发柠檬汽水了!所有的 NN 头奶牛(方便起见,编号为  ...

  2. 2019 GDUT Rating Contest III : Problem D. Lemonade Line

    题面: D. Lemonade Line Input file: standard input Output file: standard output Time limit: 1 second Memo ...

  3. PAT甲题题解-1014. Waiting in Line (30)-模拟,优先级队列

    题意:n个窗口,每个窗口可以排m人.有k为顾客需要办理业务,给出了每个客户的办理业务时间.银行在8点开始服务,如果窗口都排满了,客户就得在黄线外等候.如果有一个窗口用户服务结束,黄线外的客户就进来一个 ...

  4. Codeforces 549G Happy Line[问题转换 sort]

    G. Happy Line time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  5. ACM团队周赛题解(1)

    这次周赛题目拉了CF315和CF349两套题. 因为我代码模板较长,便只放出关键代码部分 #define ll long long #define MMT(s,a) memset(s, a, size ...

  6. EXAM-2018-7-24

    EXAM-2018-7-24 未完成 [ ] G 签到水题 A J F A:英文字母有2426个 J:注意long long D:Transit Tree Path 我直接套了单源最短路的一个模板,有 ...

  7. 【杂题1】USACO 2018 Open Contest-练习

    https://www.xoj.red/contests/show/1231 下面会写一些题目的解析什么的,当然不会粘贴题目只是简单提一下 (部分题目简单的题目就不概括了) 其实难度应该前面比较低. ...

  8. Lintcode394 Coins in a Line solution 题解

    [题目描述] There are n coins in a line. Two players take turns to take one or two coins from right side ...

  9. Lintcode395 Coins in a Line II solution 题解

    [题目描述] There are n coins with different value in a line. Two players take turns to take one or two c ...

随机推荐

  1. Oracle中Date和Timestamp的区别

    Date和Timestamp精度不一样: 01)Timestamp精确到了秒的小数点(如:2018-11-13 16:40:03.698): 02)Date只精确到整数的秒(如:2018-11-13 ...

  2. ES6的promise函数用法讲解

    总结:Promise函数的出现极大的解决了Js中的异步调用代码逻辑编写太过复杂的问题,Promise对象让异步调用函数的流程显得更加的优雅,也更容易编写. 举例: 1. 异步调用: 假设现在我的一个页 ...

  3. git push失败

    不知道弄错了什么上传项目到github上失败 git commit的时候提示 On branch masternothing to commit, working tree clean git pus ...

  4. 使用python实现解析二元一次方程

    二元一次函数的实现 import cmathimport mathimport sys 这里导入cmath包是在后面用来处理复数的情况导入math使用来处理 平方 根号等的运算而导入sys的意义是为了 ...

  5. 011 --Mysql中特定查询

    1.优化COUNT()查询 COUNT()可能是被大家误解最多的函数了,它有两种不同的作用,其一是统计某个列值的数量,其二是统计行数.统计列值时,要求列值是非空的,它不会统计NULL.如果确认括号中的 ...

  6. 买卖股票的最佳时机 II

    int maxProfit(int* prices, int pricesSize) { ; ; i < pricesSize - ; i++) { ]) { continue; } else ...

  7. python 拾遗

    三引号 可以当做多行字符串使用.在类或者方法中用的时候,可以当做docstrings来使用.具体的规则为: 该文档字符串所约定的是一串多行字符串,其中第一行以某一大写字母开始,以句号结束.第二行为空行 ...

  8. nodejs 中jead模板改为ejs

    var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set(' ...

  9. swapon和swapoff命令详解

    基础命令学习目录首页 原文链接:https://blog.csdn.net/yexiangCSDN/article/details/83182259 swapon命令用于激活Linux系统中交换空间, ...

  10. 在写ssh项目时浏览器页面出现http status 404 – not found

    HTTP Status 404 - /streetManager/index.jsp type Status report message /streetManager/index.jsp descr ...