题解 P4379 【[USACO18OPEN]Lemonade Line】
不敢快速排序又想要快排的速度,还不用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】的更多相关文章
- 洛谷 P4379 [USACO18OPEN]Lemonade Line
P4379 [USACO18OPEN]Lemonade Line 题目描述 这是农场上一个炎热的夏日,Farmer John要给他的 NN 头奶牛发柠檬汽水了!所有的 NN 头奶牛(方便起见,编号为 ...
- 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 ...
- PAT甲题题解-1014. Waiting in Line (30)-模拟,优先级队列
题意:n个窗口,每个窗口可以排m人.有k为顾客需要办理业务,给出了每个客户的办理业务时间.银行在8点开始服务,如果窗口都排满了,客户就得在黄线外等候.如果有一个窗口用户服务结束,黄线外的客户就进来一个 ...
- Codeforces 549G Happy Line[问题转换 sort]
G. Happy Line time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- ACM团队周赛题解(1)
这次周赛题目拉了CF315和CF349两套题. 因为我代码模板较长,便只放出关键代码部分 #define ll long long #define MMT(s,a) memset(s, a, size ...
- EXAM-2018-7-24
EXAM-2018-7-24 未完成 [ ] G 签到水题 A J F A:英文字母有2426个 J:注意long long D:Transit Tree Path 我直接套了单源最短路的一个模板,有 ...
- 【杂题1】USACO 2018 Open Contest-练习
https://www.xoj.red/contests/show/1231 下面会写一些题目的解析什么的,当然不会粘贴题目只是简单提一下 (部分题目简单的题目就不概括了) 其实难度应该前面比较低. ...
- 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 ...
- 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 ...
随机推荐
- Oracle中Date和Timestamp的区别
Date和Timestamp精度不一样: 01)Timestamp精确到了秒的小数点(如:2018-11-13 16:40:03.698): 02)Date只精确到整数的秒(如:2018-11-13 ...
- ES6的promise函数用法讲解
总结:Promise函数的出现极大的解决了Js中的异步调用代码逻辑编写太过复杂的问题,Promise对象让异步调用函数的流程显得更加的优雅,也更容易编写. 举例: 1. 异步调用: 假设现在我的一个页 ...
- git push失败
不知道弄错了什么上传项目到github上失败 git commit的时候提示 On branch masternothing to commit, working tree clean git pus ...
- 使用python实现解析二元一次方程
二元一次函数的实现 import cmathimport mathimport sys 这里导入cmath包是在后面用来处理复数的情况导入math使用来处理 平方 根号等的运算而导入sys的意义是为了 ...
- 011 --Mysql中特定查询
1.优化COUNT()查询 COUNT()可能是被大家误解最多的函数了,它有两种不同的作用,其一是统计某个列值的数量,其二是统计行数.统计列值时,要求列值是非空的,它不会统计NULL.如果确认括号中的 ...
- 买卖股票的最佳时机 II
int maxProfit(int* prices, int pricesSize) { ; ; i < pricesSize - ; i++) { ]) { continue; } else ...
- python 拾遗
三引号 可以当做多行字符串使用.在类或者方法中用的时候,可以当做docstrings来使用.具体的规则为: 该文档字符串所约定的是一串多行字符串,其中第一行以某一大写字母开始,以句号结束.第二行为空行 ...
- nodejs 中jead模板改为ejs
var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set(' ...
- swapon和swapoff命令详解
基础命令学习目录首页 原文链接:https://blog.csdn.net/yexiangCSDN/article/details/83182259 swapon命令用于激活Linux系统中交换空间, ...
- 在写ssh项目时浏览器页面出现http status 404 – not found
HTTP Status 404 - /streetManager/index.jsp type Status report message /streetManager/index.jsp descr ...