洛谷 P2676 [USACO07DEC]Bookshelf B

news/2024/12/12 5:46:30/

接下来我们继续看排序题单的下一道—— P2676 [USACO07DEC]Bookshelf B👇

题目描述

这道题目也是一样的,我们要透过题目所给的生活情境,直接看到它的本质所在——给定一个长度为N的正整数数列,里面的数字为乱序排列,问最少几个数加和所得到的值能够大于等于B

既然把题目理清了,那么我们来想一下如何用代码进行实现。首先它要输入数列的长度N和那个标准数B,那我们就对应定义两个int型变量分别为n,b;

在输入数列数据的时候,长度为n的数组a[n]、for循环以及for循环里面的变量i自然也少不了;

除此以外,我们要对数组的元素加和后才能判断是否大于等于给定的正整数B;

最后我们要输出的是进行加和数字的最小个数,那么毋庸置疑我们还要定义一个计数器j进行计数。

那要实现进行加和的数字个数最少,那就要从大到小进行加和。那有个问题就横亘在我们眼前了——如何对一串无序的数组进行排序,使其以从大到小的格式储存起来?

排序方法介绍

排序的方法有很多种,其中比较常用的有冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、计数排序、堆排序、桶排序、基数排序这几种(还有其他常用的也欢迎大家来补充啦),就像上一道题目车厢重组使用的其实就是冒泡排序的方法。

快速排序(Quick Sort)

今天呢着重给大家介绍一下快速排序这种方法,首先说冒泡排序大家都是了解的,就是从数组左侧开始两两比较相邻的数字,如果右侧的数字小于左侧的数字则交换两个数字的位置,如此循环一直到n-1轮时我们仅需要比较最左侧的两个数字就可以得到排序后由小到大排列的数组。反之如果要得到由大到小的数组我们只要将高亮的的“小于”改成“大于”就好了。

下面一段引自【算法】排序算法之快速排序 - 知乎 (zhihu.com)

而快速排序则是对于冒泡排序的一种优化,增加了分治策略而得到的一种高效排序算法。快速排序使用分治策略就是把一个序列分为两个子序列。

① 从数列中挑出一个元素,称为 “基准”(pivot),
② 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
③ 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

图解

用一张维基百科的动图大家可能更加清晰地了解什么是快速排序以及它是如何实现的👇

为何选择快排

这道题目在理论上使用冒泡排序也能够实现对数组的排序,但是为什么我们要使用快排而非冒泡呢?

是因为快排的时间复杂度为O(nlogn),而冒泡的的时间复杂度为O(n^2),再转眼一看,N的数据范围为(1≤N≤20,000)

那n^2已经是4*10^8,那这样的数据已经很大了,使用冒泡排序会极大的影响咱们的程序运行速率,导致超时无法AC

最后,我们使用手打快排也是可以的,但是那样会耗费大量的做题时间,比赛的时候也会拖慢我们的做题效率,故此我们大多数时候会直接使用c++STL标准库函数里面的sort(a,a+n,cmp),它对应的头文件是#include<algorithm>,或者当然啦,万能头文件也是可以的啦。

sort函数参数的意义

接下来我们来看看a、a+n以及cmp分别代表什么:

a是你要进行排序的数组的第一个元素的指针;

a+n是你要进行排序的数组的最后一个元素的下一个位置的指针;

cmp则是排序准则; 其中cmp不写的话计算机默认是从小到大进行排序,或者写less <int>()也是从小到大排序。如果我们要实现从大到小的排序,那我们就要写greater<int>(),当然如果要对double型的数据进行排序,我们就要在<>里面写double了。

至于其他的排序准则,后面我们会用到,今天就不在这里进行赘述了。

C++代码

所以这道题可以开始上AC代码啦👇

#include <bits/stdc++.h>        //万能头文件
using namespace std;
int main()
{int n,b,i,j=0,sum=0;        //定义相关变量cin >> n >> b ;int a[n];for(i=0;i<n;i++){cin >> a[i] ;}sort(a,a+n,greater<int>());        //对数据进行排序do{sum+=a[j];j++;}while(sum<b);        //用do-while循环逐步求和cout << j ;            //输出计数器的值就为最终答案return 0;
}

希望我今天讲的对大家有所帮助,如果可以的话,能否点个免费的赞支持一下博主,谢谢大家啦~~


http://www.ppmy.cn/news/628810.html

相关文章

洛谷P4089The Bovine Shuffle S 详解

# [USACO17DEC]The Bovine Shuffle S ## 题面翻译 背景 FJ 坚信快乐的牛可以产出更多的牛奶&#xff0c;因此 FJ 在牛棚里安装了一个巨大的迪斯科球并且打算让奶牛们学会跳舞。 FJ在许多出名的奶牛舞中选择了一种叫做 Bovine Shuffle 的舞蹈。这种舞蹈由 FJ 的 $N$ 头奶牛组…

P1884 [USACO12FEB]Overplanting S——洛谷

解题思路&#xff1a; 离散化 差分矩阵 解题步骤&#xff1a; 因为原始坐标系与差分的坐标系不同&#xff0c;所以要进行坐标系的变换 离散化处理缩小查找空间 图中坐标离散化后&#xff0c;再转化为格子的坐标&#xff0c;因为之前存贮的坐标是点的坐标&#xff0c;每个格…

dfs-1756:八皇后及1700:八皇后问题

总时间限制: 1000ms 内存限制: 65536kB 描述 会下国际象棋的人都很清楚&#xff1a;皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上&#xff08;有8 * 8个方格&#xff09;&#xff0c;使它们谁也不能被吃掉&#xff01;这就是著名的八皇后问题…

uva705 - Slash Maze 【转化+dfs】

题目&#xff1a;uva705 - Slash Maze 题意&#xff1a;给出一个迷宫&#xff0c;看题目给出的图就知道&#xff0c;由 \ 和 / 组成&#xff0c;让你求有几个环&#xff0c;然后最大的环由几个矩形组成。 分析&#xff1a;这是一道很灵活的题目&#xff0c;关键在于对题目给出…

洛谷 P2895 [USACO08FEB]Meteor Shower S(BFS与时间)

题目 https://www.luogu.com.cn/problem/P2895#submit 思路 有一些问题与时间有关&#xff0c;往往题目描述是&#xff1a;每隔一段时间&#xff0c;一些点就被摧毁而不能走了&#xff0c;问能够到达指定点或者到达指定点的时间&#xff1f; 这类问题可以使用BFS求解&#xf…

洛谷CF1551B

#include<stdlib.h> #include<stdio.h> using namespace std; int t; char data[55]; int flag[26];//标记所有字母是否出现过 int num1; int num2; int num; int main() { scanf("%d",&t); char temp; scanf("\n"); for(…

洛谷P2888 [USACO07NOV]Cow Hurdles S 题解

洛谷P2888 [USACO07NOV]Cow Hurdles S 题解 题目链接&#xff1a;P2888 [USACO07NOV]Cow Hurdles S 题意&#xff1a;Farmer John 想让她的奶牛准备郡级跳跃比赛&#xff0c;贝茜和她的伙伴们正在练习跨栏。她们很累&#xff0c;所以她们想消耗最少的能量来跨栏。 显然&#x…

洛谷P2768

二分真的好难/(ㄒoㄒ)/~~&#xff01; 首先看题&#xff0c;题目中我们可以知道选手跳跃最短距离的最大值&#xff0c;所以我们可以使用二分。 判断是否需要二分可以看题目中是否有类似求最短距离的最大值或者最大距离的最小值。 那么本题怎么进行二分呢 我们可以以整段距离…