洛谷【排序】算法的题单 - 笔记

2024-12-09 - 第 37 篇
洛谷【排序】题单 - 笔记
作者(Author): 郑龙浩 / 仟濹(CSND账号名)

洛谷【排序】题单合集

一、排序算法都有…

1. 简单排序算法

这些算法通常是基础的排序方法,容易理解和实现,但效率较低,适用于数据量较小的情况。

  • 冒泡排序 (Bubble Sort)
    时间复杂度:O(n²)
    空间复杂度:O(1)
    特点:重复地交换相邻的元素,直到整个序列有序。
  • 选择排序 (Selection Sort)
    时间复杂度:O(n²)
    空间复杂度:O(1)
    特点:每次选择最小的元素放到已排序部分的末尾。
  • 插入排序 (Insertion Sort)
    时间复杂度:O(n²)
    空间复杂度:O(1)
    特点:将未排序部分的元素插入到已排序部分的合适位置。

2. 分治排序算法

这些算法通过将大问题分解成小问题来解决,通常效率较高。

  • 归并排序 (Merge Sort)
    时间复杂度:O(n log n)
    空间复杂度:O(n)
    特点:通过递归分解数组并合并已经排序的子数组。
  • 快速排序 (Quick Sort)
    时间复杂度:O(n log n)(平均情况),O(n²)(最坏情况)
    空间复杂度:O(log n)(递归栈空间)
    特点:通过选择一个"基准"元素并将数组分割为小于基准和大于基准的部分,递归地排序。
  • 堆排序 (Heap Sort)
    时间复杂度:O(n log n)
    空间复杂度:O(1)
    特点:通过构建最大堆或最小堆来排序元素。

3. 线性时间排序算法

这些算法的时间复杂度是 O(n),适用于特定类型的数据。

  • 计数排序 (Counting Sort)
    时间复杂度:O(n + k)
    空间复杂度:O(k)
    特点:通过统计数组中每个元素的出现次数,适用于元素范围较小的情况。
  • 桶排序 (Bucket Sort)
    时间复杂度:O(n + k)(最理想情况)
    空间复杂度:O(n)
    特点:将元素分配到不同的桶中,然后分别排序桶内的元素。
  • 基数排序 (Radix Sort)
    时间复杂度:O(nk)
    空间复杂度:O(n + k)
    特点:按位(从低位到高位)进行排序,适用于整数或字符串排序。

4. 非比较排序算法

这些排序算法通过特定方式排序,不依赖于元素的比较,因此能在某些特定情况下达到线性时间复杂度。

  • 计数排序桶排序基数排序 都属于非比较排序,它们利用额外的信息(例如元素的计数、元素分布或位数)来直接排定顺序。

5. 其他排序算法

  • 希尔排序 (Shell Sort)
    时间复杂度:O(n log n)(最优情况),O(n²)(最坏情况)
    空间复杂度:O(1)
    特点:是插入排序的一种改进,采用了分组插入排序,逐步减少间隔来进行排序。
  • 双向冒泡排序 (Cocktail Shaker Sort)
    时间复杂度:O(n²)
    空间复杂度:O(1)
    特点:是冒泡排序的变种,优化了冒泡过程,双向交替进行排序。

总结:排序算法的分类与选择

  • 简单排序(冒泡、选择、插入排序)适用于数据量较小的场景。
  • 分治算法(快速、归并、堆排序)是更高效的排序方法,适用于数据量较大的情况。
  • 线性时间排序(计数、桶、基数排序)适用于特定场景,尤其是在数据范围已知的情况下。

不同的排序算法有不同的应用场景和优缺点,选择排序算法时要考虑输入数据的特点和所需的性能要求。

二、洛谷算法题合集 (基本上都是使用的 sort 函数)

题目顺序 由简到难

1. P2676 [USACO07DEC] Bookshelf B

难度【入门】

题目描述

Farmer John 最近为奶牛们的图书馆添置了一个巨大的书架,尽管它是如此的大,但它还是几乎瞬间就被各种各样的书塞满了。现在,只有书架的顶上还留有一点空间。

所有 N ( 1 ≤ N ≤ 20 , 000 ) N(1 \le N \le 20,000) N(1N20,000) 头奶牛都有一个确定的身高 H i ( 1 ≤ H i ≤ 10 , 000 ) H_i(1 \le H_i \le 10,000) Hi(1Hi10,000)。设所有奶牛身高的和为S。书架的高度为 B B B,并且保证 1 ≤ B ≤ S < 2 , 000 , 000 , 007 1 \le B \le S < 2,000,000,007 1BS<2,000,000,007

为了够到比最高的那头奶牛还要高的书架顶,奶牛们不得不像演杂技一般,一头站在另一头的背上,叠成一座“奶牛塔”。当然,这个塔的高度,就是塔中所有奶牛的身高之和。为了往书架顶上放东西,所有奶牛的身高和必须不小于书架的高度。

显然,塔中的奶牛数目越多,整座塔就越不稳定,于是奶牛们希望在能够到书架顶的前提下,让塔中奶牛的数目尽量少。 现在,奶牛们找到了你,希望你帮她们计算这个最小的数目。

输入格式
  • 1 1 1 行: 2 个用空格隔开的整数: N N N B B B
  • 2 … N + 1 2\dots N+1 2N+1 行: 第 i + 1 i+1 i+1 行是 1 1 1 个整数: H i H_i Hi
输出格式
  • 1 1 1 行: 输出 1 1 1 个整数,即最少要多少头奶牛叠成塔,才能够到书架顶部
样例 #1
样例输入 #1
6 40
6
18
11
13
19
11
样例输出 #1
3

提示

输入说明:

一共有 6 6 6 头奶牛,书架的高度为 40 40 40,奶牛们的身高在 6 … 19 6\dots19 619之间。

输出说明:

一种只用 3 3 3 头奶牛就达到高度 40 40 40 的方法: 18 + 11 + 13 18+11+13 18+11+13。当然还有其他方法,在此不一一列出了。

本题代码:

// P2676-Bookshelf_B
// 使用 sort 函数,快速排序
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
bool cmp( int a, int b ){return a > b;
}
int main( void ){int num, shelf_height; // 奶牛数量,书架高度vector<int> cows_height; // 奶牛高度int sum = 0; // 叠罗汉的奶牛数量cin >> num >> shelf_height;for( int i = 0; i < num; i++ ){int temp;cin >> temp;cows_height.push_back( temp );}sort( cows_height.begin(), cows_height.end(), cmp ); // sort 默认升序,所以可以写一个cmp函数来实现降序for( int i = 0; i < cows_height.size(); i++ ){sum += cows_height[i];if( sum >= shelf_height ){cout << i + 1;break;}}return 0;
}

2.P1152欢乐的跳

难度【入门】

题目描述

一个 n n n 个元素的整数数组,如果数组两个连续元素之间差的绝对值包括了 [ 1 , n − 1 ] [1,n-1] [1,n1] 之间的所有整数,则称之符合“欢乐的跳”,如数组 { 1 , 4 , 2 , 3 } \{1,4,2,3\} {1,4,2,3} 符合“欢乐的跳”,因为差的绝对值分别为: 3 , 2 , 1 3,2,1 3,2,1

给定一个数组,你的任务是判断该数组是否符合“欢乐的跳”。

输入格式

每组测试数据第一行以一个整数 n ( 1 ≤ n ≤ 1000 ) n(1 \le n \le 1000) n(1n1000) 开始,接下来 n n n 个空格隔开的在 [ − 1 0 8 , 1 0 8 ] [-10^8,10^8] [108,108] 之间的整数。

输出格式

对于每组测试数据,输出一行若该数组符合“欢乐的跳”则输出 Jolly,否则输出 Not jolly

样例 #1
样例输入 #1
4 1 4 2 3
样例输出 #1
Jolly
样例 #2
样例输入 #2
5 1 4 2 -1 6
样例输出 #2
Not jolly
提示

1 ≤ n ≤ 1000 1 \le n \le 1000 1n1000

本题代码:

// 洛谷P1152 欢乐的跳
// 思路:
// 1. 输入数据
// 2. 将相邻两个元素的差值的绝对值存入第二个数组 arr2中
// 3. 将 arr2 差值的绝对值组成的数组 --> 从大到小排序
// 3. 只需比较最大的元素,如果最大的元素 范围在[1, n-1],而是 “欢乐的跳”, 否则不是“欢乐的跳”
// 3. 条件:数组宽度 1 <= n <= 1000
// 4. 条件:数组元素 -10^8 <= arr[ i ] <= 10^8
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
bool compare( long long a, long long b ){return a > b;
}
int main( void ){vector <long long> arr; // 存储元素vector <long long> arr2;int n; // 数组宽度cin >> n;// 输入数据for( int i = 0; i < n; i++ ){int temp;cin >> temp;arr.push_back( temp );}// 计算相邻两个元素的差值的绝对值for( int i = 0; i < n - 1; i++ ){arr2.push_back( abs( arr[ i ] - arr[ i + 1 ] ) );}// 排序sort( arr2.begin(), arr2.end(), compare );// 比较if( arr2[ 0 ] >= 1 && arr2[ 0 ] <= n - 1 ){cout << "Jolly" << endl;}else{cout << "Not jolly" << endl;}return 0;
}

3.【深基9.例1】选举学生会

难度【普及-】

题目描述

学校正在选举学生会成员,有 n n n n ≤ 999 n\le 999 n999)名候选人,每名候选人编号分别从 1 1 1 n n n,现在收集到了 m m m m ≤ 2000000 m \le 2000000 m2000000)张选票,每张选票都写了一个候选人编号。现在想把这些堆积如山的选票按照投票数字从小到大排序。

输入格式

输入 n n n m m m 以及 m m m 个选票上的数字。

输出格式

求出排序后的选票编号。

样例 #1
样例输入 #1
5 10
2 5 2 2 5 2 2 2 1 2
样例输出 #1
1 2 2 2 2 2 2 2 5 5

本题代码:

// 洛谷 P1270 选举学生会
// 思路: 正常排序,没什么特殊的
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main( void ){int num, m; // 人员编号 人数vector<int> arr;cin >> num >> m; // 输入界限// 输入数据for( int i = 0; i < m; i++ ){int temp;cin >> temp;arr.push_back( temp );}// 排序sort( arr.begin(), arr.end() ); // 默认升序排序即可for( int i = 0; i < m; i++ ){cout << arr.at( i ) << " ";}return 0;
}

4.【模板】排序

难度【普及-】

题目描述

将读入的 N N N 个数从小到大排序后输出。

输入格式

第一行为一个正整数 N N N

第二行包含 N N N 个空格隔开的正整数 a i a_i ai,为你需要进行排序的数。

输出格式

将给定的 N N N 个数从小到大输出,数之间空格隔开,行末换行且无空格。

样例 #1
样例输入 #1
5
4 2 4 5 1
样例输出 #1
1 2 4 4 5
提示

对于 20 % 20\% 20% 的数据,有 1 ≤ N ≤ 1 0 3 1 \leq N \leq 10^3 1N103

对于 100 % 100\% 100% 的数据,有 1 ≤ N ≤ 1 0 5 1 \leq N \leq 10^5 1N105 1 ≤ a i ≤ 1 0 9 1 \le a_i \le 10^9 1ai109

本题代码:

// 洛谷P11177 【模板】排序
// 排序依然是正常排序,需要注意的是细节:【输出格式】行末换行且无空格 --> 这句话意味着需要进行“特判”,行末无空格,而是\n
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main ( void ){int num; // 限制长度vector <int> arr; // 存储数据cin >> num; // 输入数据for( int i = 0; i < num; i++ ){int temp;cin >> temp;arr.push_back( temp );}// 排序sort( arr.begin(), arr.end() ); // 默认升序排序即可for( auto i = arr.begin(); i!= arr.end(); i++ ){cout << *i;if( i!= arr.end() - 1 ){cout << " ";}else{cout << endl;}} // 注意:行末无空格,而是\n ( 最后一个元素后面无空格,而是\n)return 0;
}

5. 【深基9.例4】求第 k 小的数

难度【普及-】

题目描述

输入 n n n 1 ≤ n < 5000000 1 \le n < 5000000 1n<5000000 n n n 为奇数)个数字 a i a_i ai 1 ≤ a i < 10 9 1 \le a_i < {10}^9 1ai<109),输出这些数字的第 k k k 小的数。最小的数是第 0 0 0 小。

请尽量不要使用 nth_element 来写本题,因为本题的重点在于练习分治算法。

输入格式
输出格式
样例 #1
样例输入 #1
5 1
4 3 2 1 5
样例输出 #1
2

本题代码:

// 洛谷P1923 第 k 小的数
// 本来的思路是使用 sort 进行排序,然后查找第 k 个元素,但是当数据非常多的时候,超时了
// 然后看了题解以后,发现了一个非常好用的方法,nth_element()方法,然后在CSDN上看了一下如何使用,才用的这个方法
// 注意:在写nth_element()方法的时候,第二个参数无需 k - 1,因为题干中明确指出了【k从0开始】,也就是意味着,k与下标是对齐的
// 注意: 使用cin输入数组的时候,运算会超时,改用scanf就不会超时了
#include <iostream>
#include <algorithm>
using namespace std;
int main ( void ){int arr[ 5000000 ];int n, k;cin >> n >> k;for( int i = 0; i < n; i++ ){scanf( "%d", &arr[ i ]);}nth_element( arr, arr + k, arr + n ); // 使用该方法,查找 第 k 小的数cout << arr[ k ];return 0;
}

6.[NOIP2006 普及组] 明明的随机数

难度【普及-】

题目描述

明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了 N N N 1 1 1 1000 1000 1000 之间的随机整数 ( N ≤ 100 ) (N\leq100) (N100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。

输入格式

输入有两行,第 1 1 1 行为 1 1 1 个正整数,表示所生成的随机数的个数 N N N

2 2 2 行有 N N N 个用空格隔开的正整数,为所产生的随机数。

输出格式

输出也是两行,第 1 1 1 行为 1 1 1 个正整数 M M M,表示不相同的随机数的个数。

2 2 2 行为 M M M 个用空格隔开的正整数,为从小到大排好序的不相同的随机数。

样例 #1
样例输入 #1
10
20 40 32 67 40 20 89 300 400 15
样例输出 #1
8
15 20 32 40 67 89 300 400
提示

NOIP 2006 普及组 第一题

本题代码:

// 洛谷P1059 明明的随机数
// 两种思路:
// 1. 先排序,后去重
// 2. 使用桶排序,下标既是数,元素有值,则证明该数被输入了,最后遍历数组,将>=1的元素输出
// 我使用的 桶排序 方法
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main( void ){int n;int sum = 0;int arr[ 1001 ] = {0}; // 桶排序,下标是数,值是出现的次数cin >> n;for( int i = 0; i < n; i ++ ){int temp;cin >> temp;if( arr[ temp ] == 0 ){sum ++;arr[ temp ] ++;}elsecontinue;}cout << sum << endl;// 遍历数组,输出>=1的元素for( int i = 0; i < 1001; i++ ){if( arr[ i ] >= 1 ){cout << i << " ";}}return 0;
}

7.[NOIP2007 普及组] 奖学金

难度【普及-】

题目背景

NOIP2007 普及组 T1

题目描述

某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前 5 5 5 名学生发奖学金。期末,每个学生都有 3 3 3 门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学排在前面,这样,每个学生的排序是唯一确定的。

任务:先根据输入的 3 3 3 门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前五名名学生的学号和总分。

注意,在前 5 5 5 名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。例如,在某个正确答案中,如果前两行的输出数据(每行输出两个数:学号、总分) 是:

7 279  
5 279

这两行数据的含义是:总分最高的两个同学的学号依次是 7 7 7 号、 5 5 5 号。这两名同学的总分都是 279 279 279 (总分等于输入的语文、数学、英语三科成绩之和) ,但学号为 7 7 7 的学生语文成绩更高一些。

如果你的前两名的输出数据是:

5 279  
7 279

则按输出错误处理,不能得分。

输入格式

n + 1 n+1 n+1 行。

1 1 1 行为一个正整数 n ≤ 300 n \le 300 n300,表示该校参加评选的学生人数。

2 2 2 n + 1 n+1 n+1 行,每行有 3 3 3 个用空格隔开的数字,每个数字都在 0 0 0 100 100 100 之间。第 j j j 行的 3 3 3 个数字依次表示学号为 j − 1 j-1 j1 的学生的语文、数学、英语的成绩。每个学生的学号按照输入顺序编号为 1 ∼ n 1\sim n 1n(恰好是输入数据的行号减 1 1 1)。

保证所给的数据都是正确的,不必检验。

输出格式

5 5 5 行,每行是两个用空格隔开的正整数,依次表示前 5 5 5 名学生的学号和总分。

样例 #1
样例输入 #1
6
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98
样例输出 #1
6 265
4 264
3 258
2 244
1 237
样例 #2
样例输入 #2
8
80 89 89
88 98 78
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98
样例输出 #2
8 265
2 264
6 264
1 258
5 258

本题代码:

// 洛谷P1093 奖学金
// 思路: 首先这是一道 结构题 + 排序 的题
// 1. 定义一个结构体,存放数据 -->  学号 + 语文成绩 + 数学成绩 + 英语成绩 + 总分
// 2. 编写比较函数 compare --> sort函数需要使用
// 3. 使用sort函数进行排序
// 4. 正常打印
#include <iostream>
#include <algorithm>
using namespace std;
struct student{int id; // 存放学号int chinese; // 存放语文成绩int math; // 存放数学成绩int english; // 存放英语成绩int sum; // 存放总分
};
// 排序规则 --> sort 函数需要使用的【排序函数】
bool compare( student a, student b ){if ( a.sum != b.sum ) // 如果前后两者总成绩 【不相同】 --> 按照总分排序return a.sum > b.sum; else if ( a.chinese!= b.chinese ) // 总成绩 相同 && 语文成绩 【不相同】 --> 按照语文成绩排序return a.chinese > b.chinese;else // 总成绩 相同 && 语文成绩 相同 && 学号 【不相同】 --> 按照学号排序return a.id < b.id;
}
int main( void ){student score[ 305 ]; // 存放学号 + 成绩 + 总成绩int num;cin >> num; // 输入学生人数for( int i = 0; i < num; i++ ){cin >> score[ i ].chinese >> score[ i ].math >> score[ i ].english; // 存放 语 数 英 成绩score[ i ].sum = score[ i ].chinese + score[ i ].math + score[ i ].english; // 计算 总分score[ i ].id = i + 1; // 存放 学号}// 按照规则进行排序sort( score, score + num, compare );// 正常打印for( int i = 0; i < 5; i++ ){cout << score[ i ].id << " " << score[ i ].sum << endl;}return 0;
}

8.宇宙总统

难度【普及-】

题目描述

地球历公元 6036 年,全宇宙准备竞选一个最贤能的人当总统,共有 n n n 个非凡拔尖的人竞选总统,现在票数已经统计完毕,请你算出谁能够当上总统。

输入格式

第一行为一个整数 n n n,代表竞选总统的人数。

接下来有 n n n 行,分别为第一个候选人到第 n n n 个候选人的票数。

输出格式

共两行,第一行是一个整数 m m m,为当上总统的人的号数。

第二行是当上总统的人的选票。

样例 #1
样例输入 #1
5
98765
12365
87954
1022356
985678
样例输出 #1
4
1022356
提示

票数可能会很大,可能会到 100 100 100 位数字。

1 ≤ n ≤ 20 1 \leq n \leq 20 1n20

本题代码:

// 洛谷P1781 宇宙总统
// 该题需要使用 “高精度整数 / 或者直接存储为字符串”,因为最大100位数,普通类型存储不开
// 用结构体存储 “第n人” + “选票数量” + “票数长度”
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct ddd{int n; // 第n人char num[ 101 ]; // 选票数量 --> 因为数据太大,所以需要用 字符数组int len; // 票数长度
};
bool cmp( ddd a, ddd b ){if( a.len != b.len )return a.len > b.len; // 按票数长度降序 --> 长度若大,则百分百票数大elsereturn strcmp( a.num, b.num ) > 0; // 按票数降序 --> 票数越多,越在前
}
int main( void ){int num; // 竞选总统人数cin >> num;ddd president[ num ];for( int i = 0; i < num; i++ ){cin >> president[ i ].num; // 输入选票数量president[ i ].n = i + 1; // 第几个人president[ i ].len = strlen( president[ i ].num ); // 计算票数长度}sort( president, president + num, cmp ); // 排序cout << president[ 0 ].n << endl; // 输出最大票数的人的编号cout << president[ 0 ].num << endl; // 输出最大票数的人的票数return 0;
}

9.车厢重组

难度【普及-】

题目描述

在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转 180 180 180 度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。他退休后,火车站决定将这一工作自动化,其中一项重要的工作是编一个程序,输入初始的车厢顺序,计算最少用多少步就能将车厢排序。

输入格式

共两行。

第一行是车厢总数 N ( ≤ 10000 ) N( \le 10000) N(10000)

第二行是 N N N 个不同的数表示初始的车厢顺序。
:实际上数据中并不都在同一行,有可能分行输入)

输出格式

一个整数,最少的旋转次数。

样例 #1
样例输入 #1
4
4 3 2 1
样例输出 #1
6

本题代码:

// 洛谷P1116 车厢重组 // 一定要记住:即使只计算【步数】,依然要进行中间的【交换】,刚开始做我就犯了这个错,后来才发现!!!!// 该题 使用冒泡的算法,而题目中并未指出要排序,我们不可以省去排序的步骤!!直接打印出题目中想要的 “步数”
// 注:千万不要因为只计算【步骤】,省去【交换】的步骤,这样做出来的答案是错误的,因为既然没有进行交换,那么大数一直没有放到最后边,导致数组中的
// 数据没次循环都是一样的,每次循环大数的位置不是在最后边,所以我们需要进行交换,才能得到正确的答案!!!// 思路:依次循环,每次循环将最大的数字,冒泡到 最后面
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;int main( void ){int num; // 车厢数量cin >> num;int ans = 0; // 存储结果 --> 步数vector <int> arr ( num ); // 存储车厢for( int i = 0; i < num; i++ ) // 输入cin >> arr[ i ];for( int i = 0; i < num - 1; i ++ ){ //表示次数,次数为 num - 1 次,因为最后一个数,不需要再循环for( int j = 0; j < num - 1 - i; j ++ ){ // 每次循环,将最大的数,冒泡到最后面,排到 i 位置 ,所以是 1 到 iif( arr[ j ] > arr[ j + 1 ] ){ // 因为是从小到大排,所以如果【当前位置】> 【下一个位置】,则交换位置,并且步数 + 1swap( arr[ j ], arr[ j + 1 ] ); // 交换两数ans ++;}}}cout << ans << endl;return 0;
}

10. [NOIP2009 普及组] 分数线划定

难度【普及-】

题目描述

世博会志愿者的选拔工作正在 A 市如火如荼的进行。为了选拔最合适的人才,A 市对所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试。面试分数线根据计划录取人数的 150 % 150\% 150% 划定,即如果计划录取 m m m 名志愿者,则面试分数线为排名第 m × 150 % m \times 150\% m×150%(向下取整)名的选手的分数,而最终进入面试的选手为笔试成绩不低于面试分数线的所有选手。

现在就请你编写程序划定面试分数线,并输出所有进入面试的选手的报名号和笔试成绩。

输入格式

第一行,两个整数 n , m ( 5 ≤ n ≤ 5000 , 3 ≤ m ≤ n ) n,m(5 \leq n \leq 5000,3 \leq m \leq n) n,m(5n5000,3mn),中间用一个空格隔开,其中 n n n 表示报名参加笔试的选手总数, m m m 表示计划录取的志愿者人数。输入数据保证 m × 150 % m \times 150\% m×150% 向下取整后小于等于 n n n

第二行到第 n + 1 n+1 n+1 行,每行包括两个整数,中间用一个空格隔开,分别是选手的报名号 k ( 1000 ≤ k ≤ 9999 ) k(1000 \leq k \leq 9999) k(1000k9999)和该选手的笔试成绩 s ( 1 ≤ s ≤ 100 ) s(1 \leq s \leq 100) s(1s100)。数据保证选手的报名号各不相同。

输出格式

第一行,有 2 2 2 个整数,用一个空格隔开,第一个整数表示面试分数线;第二个整数为进入面试的选手的实际人数。

从第二行开始,每行包含 2 2 2 个整数,中间用一个空格隔开,分别表示进入面试的选手的报名号和笔试成绩,按照笔试成绩从高到低输出,如果成绩相同,则按报名号由小到大的顺序输出。

样例 #1
样例输入 #1
6 3 
1000 90 
3239 88 
2390 95 
7231 84 
1005 95 
1001 88
样例输出 #1
88 5 
1005 95 
2390 95 
1000 90 
1001 88 
3239 88
提示

【样例说明】

m × 150 % = 3 × 150 % = 4.5 m \times 150\% = 3 \times150\% = 4.5 m×150%=3×150%=4.5,向下取整后为 4 4 4。保证 4 4 4 个人进入面试的分数线为 88 88 88,但因为 88 88 88 有重分,所以所有成绩大于等于 88 88 88 的选手都可以进入面试,故最终有 5 5 5 个人进入面试。

NOIP 2009 普及组 第二题

本题代码:

// 洛谷P1068 分数线划定
// 题目有点长,读了一阵子才读明白题意
// 总而言之,就是有一堆人,然后输入n(参赛人数),m(录取人数) 其中:( m * 150% ) <= n 如果 ( m * 150% )为小数,则向下取整 4.5 取 4
// 注意:如果最后的【分数线】是重分,则要将最后一个重分的人也输出,并且输出人数也要 + 1
// 思路:
// 1. 输入 n 和 m
// 2. 输入 n 个分数,存储到数组中
// 3. 对数组进行排序,从大到小
// 4. 计算出 m * 1.5 向下取整的数 new_m,并且判断: 如果arr[ new_m ] 为 重分,则要将【所有重分的人的分数都打印出来,且 new_m ++】
// 5. 输出分数线,以及分数线的人数
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct ddd{int score; // 存放分数int id; // 存放编号
};
bool cmp( ddd a, ddd b ){if( a.score == b.score ) // 如果分数相等,则按照编号从小到大排序return a.id < b.id;return a.score > b.score;
}
int main( void ){int n, m, new_m; // 参赛人数,录取人数, m * 1.5 向下取整cin >> n >> m;ddd arr[ 5001 ]; // 存放分数, 编号 --> 注意:定义数组的时候,千万不要将 5001 写成 变量n,否则,答案会出错for( int i = 0; i < n; i ++ ){ // 输入分数scanf( "%d%d", &arr[ i ].id, &arr[ i ].score );}// 注意: 先排序,后计算 new_m 的大小sort( arr, arr + n, cmp ); // 排序 --> 从大到小 --> 所有人都要排序,因为有重分的情况会出现,这种情况也要排序,并且记入 new_m 中new_m = m * 1.5; // 分数线 --> 如果是小数,则向下取整 --> 实际上就是【数据截断】// 处理【重分】的情况 --> whilewhile( arr[ new_m - 1 ].score == arr[ new_m ].score && new_m < n ){ // 每次循环,如果 分数相同,则 new_m ++ && 保证不越界(new_m < n)new_m ++;}printf( "%d %d\n", arr[ new_m - 1 ], new_m); // 输出分数线,以及分数线的人数for( int i = 0; i < new_m; i ++ ){ // 输出分数线的人的编号printf( "%d %d\n", arr[ i ].id, arr[ i ].score ); }return 0;
}

11.攀爬者

难度【普及-】

题目背景

HKE 考完 GDOI 之后跟他的神犇小伙伴们一起去爬山。

题目描述

他在地形图上标记了 N N N 个点,每个点 P i P_i Pi 都有一个坐标 ( x i , y i , z i ) (x_i,y_i,z_i) (xi,yi,zi)。所有点对中,高度值 z z z 不会相等。HKE 准备从最低的点爬到最高的点,他的攀爬满足以下条件:

(1) 经过他标记的每一个点;

(2) 从第二个点开始,他经过的每一个点高度 z z z 都比上一个点高;

(3) HKE 会飞,他从一个点 P i P_i Pi 爬到 P j P_j Pj 的距离为两个点的欧几里得距离。即, ( X i − X j ) 2 + ( Y i − Y j ) 2 + ( Z i − Z j ) 2 \sqrt{(X_i-X_j)^2+(Y_i-Y_j)^2+(Z_i-Z_j)^2} (XiXj)2+(YiYj)2+(ZiZj)2

现在,HKE 希望你能求出他攀爬的总距离。

输入格式

第一行,一个整数 N N N 表示地图上的点数。

接下来 N N N 行,三个整数 x i , y i , z i x_i,y_i,z_i xi,yi,zi 表示第 i i i 个点的坐标。

输出格式

一个实数,表示 HKE 需要攀爬的总距离(保留三位小数)

样例 #1
样例输入 #1
5
2 2 2
1 1 1
4 4 4
3 3 3
5 5 5
样例输出 #1
6.928
提示

对于100%的数据, 1 ≤ N ≤ 50000 1\leq N\leq 50000 1N50000,答案的范围在 double 范围内。

本题代码:

// 洛谷P5143 攀爬者
// 本题方法:1. 使用 ”结构体”数组存储“坐标” 2.  按照“高度”对结构体进行排序  3. 遍历数据,按照数学公式计算距离并且累加距离#include <iostream>
#include <algorithm>
#include <cmath>using namespace std;
struct ddd{int x, y, z; // 存放坐标
};
// 比较函数 - 排序规则:按照高度 从小到大 排序
bool cmp( ddd a, ddd b ){return b.z > a.z; // 按照高度 从小到大 排序
}
int main( void ){ddd point[ 50000 ]; // 存放坐标int n; // 存放坐标的个数cin >> n; // 输入坐标的个数// 输入坐标for( int i = 0; i < n; i ++ ){cin >> point[ i ].x >> point[ i ].y >> point[ i ].z;}sort( point, point + n, cmp ); // 按照高度进行由小到大排序double sum = 0; // 存放总距离// 遍历数据,按照数学公式计算距离并且累加距离for( int i = 0; i < n - 1; i ++ ){ // 为什么是 n - 1 呢?因为 我循环中所写的是: 当前位置 与 后一个位置,// 所以我只需要循环到 point[ n - 2 ] 即可,因为最后一个循环计算的是 point[ n - 1 ] 与 point[ n - 2 ] 的距离int new_x = point[ i ].x - point[ i + 1 ].x; // 存储 两个点的 x 坐标的差值int new_y = point[ i ].y - point[ i + 1 ].y; // 存储 两个点的 y 坐标的差值int new_z = point[ i ].z - point[ i + 1 ].z; // 存储 两个点的 z 坐标的差值sum += sqrt( new_x * new_x + new_y * new_y + new_z * new_z ); // 计算距离并累加距离}printf( "%.3lf\n", sum ); // 输出总距离 --> 保留 3 位小数return 0;
}

12.生日

难度【普及-】

题目描述

cjf 君想调查学校 OI 组每个同学的生日,并按照年龄从大到小的顺序排序。但 cjf 君最近作业很多,没有时间,所以请你帮她排序。

输入格式

输入共有 n + 1 n + 1 n+1 行,

1 1 1 行为 OI 组总人数 n n n

2 2 2 行至第 n + 1 n+1 n+1 行分别是每人的姓名 s s s、出生年 y y y、月 m m m、日 d d d

输出格式

输出共有 n n n 行,

n n n 个生日从大到小同学的姓名。(如果有两个同学生日相同,输入靠后的同学先输出)

样例 #1
样例输入 #1
3
Yangchu 1992 4 23
Qiujingya 1993 10 13
Luowen 1991 8 1
样例输出 #1
Luowen
Yangchu
Qiujingya
提示

数据保证, 1 < n < 100 1<n<100 1<n<100 1 ≤ ∣ s ∣ < 20 1\leq |s|<20 1s<20。保证年月日实际存在,且年份 ∈ [ 1960 , 2020 ] \in [1960,2020] [1960,2020]

本题代码:

// 洛谷P1104 生日
// 思路:
// 1. 使用 结构体数组 存储人员信息
// 2. 按照 年龄 进行 排序 --> 使用sort函数,比较函数规则:先按照年,再按照月,再按照日,如果都相等,后输入的在前
// 注意:输入靠后的在前,刚开始看错了,看成了先输入的靠前,导致错了
// 3. 输出 结构体数组 中 第 k 个 元素的 姓名
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;// 定义结构体 --> 存储 姓名 年月日 输入顺序
struct ddd{string name;int year, month, day;int num; // 输入顺序 -> 为了方便排序:若年龄相同,则 先输入的 排在 前面
};
// 比较函数 --> 按照年龄进行排序的规则
bool cmp( ddd a, ddd b ){if( a.year != b.year )return a.year < b.year; // 年 小的在前 即 年龄大的在前else if( a.month != b.month )return a.month < b.month; // 月 小的在前 即 年龄大的在前else if( a.day != b.day )return a.day < b.day; // 日 小的在前,即 年龄大的在前elsereturn a.num > b.num; // 输入顺序 小的在前 即 如果年龄完全相等,输入靠后的在前// 一定要注意: 输入靠后的在前,不是输入靠前的在前
}
int main( void ){int n; // 总人数ddd peo[ 100 ]; // 存储人员信息cin >> n; // 输入总人数// 输入人员信息for( int i = 0; i < n; i ++ ){cin >> peo[ i ].name >> peo[ i ].year >> peo[ i ].month >> peo[ i ].day;peo[ i ].num = i + 1; // 记录输入顺序}sort( peo, peo + n, cmp ); // 按照年龄进行排序for( int i = 0; i < n; i ++ ){cout << peo[ i ].name << endl;}cout << endl;return 0;
}

13.[NOIP1998 提高组] 拼数

难度【普及/提高-】

题目描述

设有 n n n 个正整数 a 1 … a n a_1 \dots a_n a1an,将它们联接成一排,相邻数字首尾相接,组成一个最大的整数。

输入格式

第一行有一个整数,表示数字个数 n n n

第二行有 n n n 个整数,表示给出的 n n n 个整数 a i a_i ai

输出格式

一个正整数,表示最大的整数

样例 #1
样例输入 #1
3
13 312 343
样例输出 #1
34331213
样例 #2
样例输入 #2
4
7 13 4 246
样例输出 #2
7424613
提示

对于全部的测试点,保证 1 ≤ n ≤ 20 1 \leq n \leq 20 1n20 1 ≤ a i ≤ 1 0 9 1 \leq a_i \leq 10^9 1ai109

NOIP1998 提高组 第二题

本题代码:

// 洛谷P1012 拼数
// 思路:
// 本题的排序不是正常的排序,不是比较数值大小 --> 因为是要求出数字拼一起的最大值,所以排序应该是 两数不同顺序相加 哪个字典序大哪个在前...
// 实际上也就是字符串比较
// 1. 使用 字符串数组 存储 数字 --> 因为本题的排序是基于“字符串”而不是“数值”
// 2. 定义比较函数 --> 按照 字符串 进行比较 --> 啊+ b 与 b + a 字符串相加, 哪个字典序大哪个在前 --> 注意:字符串比较是从第一位向最后一位比较,大的在前
// 3. 输出 字符串数组 中 所有 元素的 字符串
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;// 定义比较函数
bool cmp( string a, string b ){return a + b > b + a; // 相加 在再比较 --> 大的在前 我刚开始就写错了,写成了 a > b 因为是相加后最大的,所以比较的时候也要进行相加
}
int main( void ){string arr[ 20 ]; // 存放 <= 20 个字符串int n; // 输入的字符串的个数cin >> n; // 输入字符串的个数// 输入字符串for( int i = 0; i < n; i ++ ){cin >> arr[ i ];}sort ( arr, arr + n, cmp ); // 按字符串比较 大的在前// 打印字符串for( int i = 0; i < n; i ++ ){cout << arr[ i ];}cout << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/63477.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL--》如何在SQL中巧妙运用函数与约束,优化数据处理与验证?

目录 函数使用 字符串函数 数值函数 日期函数 流程函数 约束 函数使用 函数是指一段可以直接被另一段程序调用的程序或代码&#xff0c;在mysql当中有许多常见的内置函数&#xff0c;接下来开始对这些内置函数及其作用进行简单的讲解和使用&#xff1a; 字符串函数 my…

归有光,情感与真实的独行者

归有光&#xff0c;字熙甫&#xff0c;号震川&#xff0c;生于明孝宗弘治十年&#xff08;公元1507年&#xff09;&#xff0c;卒于明穆宗隆庆五年&#xff08;公元1571年&#xff09;&#xff0c;享年64岁。他是中国明代著名的散文家、文学家和史学家&#xff0c;其散文风格清…

Python + OpenCV 系列:图像阈值处理

文章目录 引言 1. 阈值处理的基本概念2. OpenCV 中的阈值处理3. 常见的阈值类型3.1 二值化阈值3.2 反向二值化阈值3.3 截断阈值3.4 平滑阈值 4. 自适应阈值5. Otsu’s 阈值法6. 阈值处理的应用场景7. 总结 引言 图像阈值处理是计算机视觉和图像处理中一种非常基础而重要的技术…

计算机网络-Wireshark探索ARP

使用工具 Wiresharkarp: To inspect and clear the cache used by the ARP protocol on your computer.curl(MacOS)ifconfig(MacOS or Linux): to inspect the state of your computer’s network interface.route/netstat: To inspect the routes used by your computer.Brows…

Vue3小兔鲜电商项目

创建项目 npm install 装包

【NLP 12、深度学习15条调参经验】

反正是绚烂&#xff0c;反正是到来 反正是背负慢慢凋残的孤独 耀眼的孤独&#xff0c;义无反顾的孤独 —— 24.12.9 深度学习15条调参经验 1.调参 调参是锦上添花的事&#xff0c;而底线取决于模型的选择和数据的清洗 2.关于model ① 尽量不要自己手写模型&#xff0c;找一…

美畅物联丨视频接入网关如何配置 HTTPS 证书

在安防领域&#xff0c;视频接入网关&#xff08;Video Access Gateway&#xff0c;VAG&#xff09;是视频监控系统的重要组成部分&#xff0c;其职责是把视频数据从前端设备传输至后端服务器。配置HTTPS证书后&#xff0c;可对视频流进行加密传输&#xff0c;避免数据在网络传…

fastcam编程套料软件

Fastcam是一款功能强大的专业软件&#xff0c;以下是对它的具体介绍&#xff1a; 基本信息 • Fastcam自1982年推出首个交互式CNC编程和套料系统后&#xff0c;一直不断更新发展. • 它是为数控火焰、等离子、激光和水射流切割机等数控切割机开发的编程套料软件. 主要功能模…

【大语言模型】LangChain ModelsIO与Models I/O Promopts详解

【大语言模型】LangChain ModelsIO与Prompts详解 一、LangChain ModelsIO1、简介2、Models I/O 的应用场景3、Models I/O 主要模块3.1、Prompts3.2、Modelsa、MESSAGES 类型 3.3、Output Parsers 二、LangChain ModelsIO Prompts1、简介2、Prompts 的优点3、实战示例3.1、Promp…

MicroBlaze软核开发(三):DDR + FLASH

实现功能&#xff1a;使用 MicroBlaze软核&#xff0c;配置 DDR、Flash 接口&#xff0c;并将程序烧写固化到Flash&#xff0c;每次启动 FPGA 时自动运行 Flash 中的程序 。 Vivado版本&#xff1a;2018.3 FPGA&#xff1a;Xilinx Artix-7 系 目录 引言 Vivado部分&#xff1…

Springboot(五十三)SpringBoot3整合redisson

前边我们有记录Springboot2/3整合redis的方式。是基于Springboot默认集成的Lettuce客户端实现的。 今天我们在项目中集成的redission是在Lettuce之上构建的redis客户端。 Redisson:一个在Jedis和Lettuce之上构建的Redis客户端。提供了一系列分布式Java对象和服务,比如:分布式…

渗透测试基础

渗透测试基础是指对计算机系统、网络或应用程序进行模拟攻击&#xff0c;以发现其安全漏洞和潜在威胁的一种安全评估技术。通过模拟真实的攻击场景&#xff0c;渗透测试帮助组织了解其系统的安全弱点、验证防护措施的有效性&#xff0c;并提供改进建议。 渗透测试的核心概念 1…

ejb组件(rmi) webservice平台(xml)

springboot bean 在 Spring Boot 中&#xff0c;Bean 是 Spring 框架的核心概念之一&#xff0c;表示由 Spring 容器管理的对象。通过 Bean 或其他注解&#xff08;如 Component、Service、Repository 等&#xff09;来定义和管理这些对象。以下是关于 Spring Boot 中 Bean 的…

11.23[大数据]

PRO1:LSTM模型预测输出都是同一个值&#xff1f; 画出来的图像就是一条横线 这个搜了搜&#xff0c;原因可能有很多&#xff0c;但感觉最主要的原因极可能是激活函数选择不当&#xff0c;以及层的搭建不合适 原模型是 REF https://zhuanlan.zhihu.com/p/654325094 https:/…

基于SpringBoot+Vue的新闻管理系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着互联网技术的飞速发展&#xff0c;信息传播速度不断加快&#xff0c;新闻媒体行业面临着巨大的机遇与挑战。传统的新闻媒体正在逐渐向数字化转型&#xff0c;而新闻管理系统作为数字化新闻媒体的核心组成部分&#xff0c;其…

VCP-CLIP A visual context prompting modelfor zero-shot anomaly segmentation

GitHub - xiaozhen228/VCP-CLIP: (ECCV 2024) VCP-CLIP: A visual context prompting model for zero-shot anomaly segmentation 需要构建正样本&#xff0c;异常样本&#xff0c;以及对应的Mask

el-menu修改el-menu-item的高度后,里面的文字和图标高度没跟着变

解决方法 设置line-height的值和height一样。 <style lang"scss" scoped> .el-menu-item {height: 40px;line-height: 40px; } </style>

【C语言】完成程序设计填空

文章目录 1、请阅读下面的程序,在空白处填写正确的代码,要求各在一行从头开始输出m和n的值。2、求100~599之间的所有水仙花数,即各位数字的立方和恰好等于该数本身的数。3、以下程序的功能是:将值为三位正整数的变量x中的数值按照个位、十位、百位的顺序 拆分并输出。请填空…

MySQL-DDL之数据表操作

文章目录 一. 表的创建1. 表的创建2. 栗子 二. 查看表1. 查看数据库中的所有表2. 查看表结构 三. 删除表1. 删除表 四. 修改表结构1. 添加字段2. 修改字段3. 删除字段4. 修改表名 数据定义语言&#xff1a;简称DDL(Data Definition Language) 一. 表的创建 1. 表的创建 格式&…

【开源安全保护】如何安装JumpServer堡垒机

【开源安全保护】如何安装JumpServer堡垒机 什么是堡垒机 大家好&#xff0c;我是星哥&#xff0c;今天我以前来认识堡垒机 堡垒机&#xff08;Bastion Host&#xff09;&#xff0c;也称为跳板机&#xff08;Jump Server&#xff09;&#xff0c;是指在计算机网络中&#x…