P1177 【模板】排序 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
一道模板题,没有什么好讲的,想记录的是最后的换行判断,具体看代码:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
int n;
cin >> n;
vector<int>a(n, 0);// 开个大小为n的vector,后加逗号 零指的是里面的数字全部初始化为零,大小为n,下标就是从0到n-1
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a.begin(), a.end());//这种是针对容器的做法,具体不了解
for (int i = 0; i < n; i++) {
cout << a[i] << " \n"[i == n - 1];
}
return 0;
}
重点留意下最后的换行判断,很少见这种写法。
P1059 [NOIP2006 普及组] 明明的随机数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<iostream>
#include<algorithm>
using namespace std;
int const MAXN = 1010;
int a[MAXN], ans[MAXN], n, cnt = 0, tmp = -1;//假设tmp为-1,这样可以后续循环判断是否有重复的数字。只要tmp小于1即可。
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a, a + n);
for (int i = 0; i < n; i++) {
if (a[i] != tmp) {
ans[cnt++] = a[i];//赋值后cnt再加1.
tmp = a[i];//,将当前最大值赋给tmp,如果和tmp相同,则去重,否则加入ans中,并且更新tmp的值
}
}
cout << cnt << endl;
for (int i = 0; i < cnt; i++) {//注意这里i是要小于cnt,否则还是会输出相同数量的元素,但是变为零
cout << ans[i] << " ";
}
return 0;
}
以前写的代码,跟现在的思路完全不一样,现在想的是桶排序,虽然桶排序更优,但是原来的这种做法也有一定的学习意义,注释都写得很清楚了。
桶排序懒得写了,直接看题解里面得代码吧,上链接:(第一份就是桶排序)
P1059 [NOIP2006 普及组] 明明的随机数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
看看另外一道题目:
P1093 [NOIP2007 普及组] 奖学金 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这里主要回顾一下自定义排序函数的写法,代码贴在下面:
#include<iostream>
#include<algorithm>
using namespace std;
int const MAXN = 310;
int n;
struct student {
int id, total, chinese;
}a[MAXN];
int cmp(student a, student b) {
if (a.total != b.total)return a.total > b.total;
if (a.chinese != b.chinese)return a.chinese > b.chinese;
return a.id < b.id;
}
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
int math, english;
cin >> a[i].chinese >> math >> english;
a[i].total = a[i].chinese + english + math;
a[i].id = i + 1;
}
sort(a, a + n, cmp);
for (int i = 0; i < 5; i++) {
cout << a[i].id << " " << a[i].total << endl;
}
return 0;
}
主要还是得看清楚题目要求,写合适的cmp函数。
再看看这道相似的题目,是上面的拓展:
P1781 宇宙总统 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<iostream>
#include<algorithm>
using namespace std;
struct mem {
string x;
int num;
}s[25];
bool cmp(mem a, mem b) {
if (a.x.length() != b.x.length()) {
return a.x.length() > b.x.length();
}
return a.x > b.x;
}
int n;
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> s[i].x;
s[i].num = i;
}
sort(s + 1, s + 1 + n, cmp);
cout << s[1].num << endl << s[1].x;
return 0;
}
注意:题目提示说票数可能超过100位,所以我们就不能使用整型进行比较,而是利用字符串,显而易见的:长度长的代表的数字肯定更大,如果相同,再比较对应的大小。
P2676 [USACO07DEC] Bookshelf B - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 简单题,不讲,可以练练。
P1152 欢乐的跳 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
简单题,桶排序就行,可以练练。
另外看到题解区有位大佬写的题解,很有学习价值,可以看看。
题解 P1152 【欢乐的跳】 - 菜MKのblog - 洛谷博客 (luogu.com.cn)
再看看另外一道练手题:
P1116 车厢重组 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
其实就是冒泡排序。
P1068 [NOIP2009 普及组] 分数线划定 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这道题要注意的是:可能会有选手达到分数线,但是这时候超过预定人数的情况,只需要以分数是否大于分数线判断即可。
P1104 生日 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P5143 攀爬者 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
都是简单题,可以练练。
P1012 [NOIP1998 提高组] 拼数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这道题目有点意思,我一开始没想出怎么写,看了题解之后只感觉太奇妙了,代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
string a[25];
int n;
bool cmp(string a, string b) {
return a + b > b + a;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
sort(a + 1, a + 1 + n, cmp);
for (int i = 1; i <= n; i++) {
cout << a[i];
}
cout << endl;
return 0;
}
这个相信大家都能看懂,具体分析还是看看题解吧:
P1012 [NOIP1998 提高组] 拼数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P1923 【深基9.例4】求第 k 小的数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
快排的板子题,可以练练手,还可以学一下nth_element函数。快排的代码如下:
#include <iostream>
#define rep(i, a, b) for (int i = a; i <= (b); i++)
using namespace std;
int arr[5000000], n, k;
void qksort(int a[], int l, int r) {
int pos = l + r >> 1, i = l, j = r - 1;
swap(a[pos], a[r]);
do {
while (i <= j && a[i] < a[r])
i++;
while (i <= j && a[j] > a[r])
j--;
if (i <= j) {
swap(a[i], a[j]);
i++;
j--;
}
} while (i <= j);
swap(a[i], a[r]); // 一定有 l<=i<=r && a[i]>=a[r](a[r]即flag)
if (i > k)
qksort(a, l, i - 1);
else if (i < k)
qksort(a, i + 1, r);
}
int main() {
ios_base::sync_with_stdio(0), cin.tie(0);
cin >> n >> k;
rep(i, 0, n - 1) {
cin >> arr[i];
}
qksort(arr, 0, n - 1);
cout << arr[k];
return 0;
}
想学nth_element函数的话,看看题解区吧:
P1923 【深基9.例4】求第 k 小的数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
总结一句话: 函数语句:nth_element(数组名,数组名+第k小元素,数组名+元素个数)。