结构体,即将一个或者多个变量打包起来的整体。定义结构体的格式如下:
struct 结构体名称{
变量类型 变量名;
}结构体变量名;
或者:
struct 结构体名称{
变量类型 变量名;
}
结构体名称 结构体变量名;
例如,一个学生的姓名、年龄、身高可以这样包装:
struct node{
string name;
int age;
float h;
}stu[1001];
常见的排序有:冒泡排序、选择排序、归并排序、二分排序和桶排序等。不过这里我不多做介绍,我将要提的是一个c++库中的排序函数:sort()。sort称为快排,速度非常的快。括号里的参数分别是起始位置和结束位置,在这之间的变量都将被排序。默认的排序是从小到大,不过我们可以通过加入第三个参数来让函数从大到小地排。假设有一个长度为n的整数数组a,要对整个数组进行从大到小地排列只需要在主函数外写一个比较函数,然后把函数作为第三个参数塞进sort的括号里就可以了。函数写法如下:
bool cmp(const int &x, const int &y){
return x > y;
}
然后将函数写在sort里:
sort(a, a + n, cmp);
就可以实现从大到小排列了。这里要注意的是sort的头文件为<algorithm>,不要忘记加上了。
接下来我们看看下面这个习题:
平均分排序
Description
小信所在的年级有 N 个班,年级组长希望 将各个班这次期末考试的平均分排序,从平均分最低到最高排序。请你设计程序帮助年级组长完成这个工作。
Input
输入第一行为小信所在年级的班数——整数 N(0≤N≤100)。
接下来 N 行每行是每个班的平均分(大于等于 0.0,小于等于 100.0)。
Output
输出 N 行,为各班平均分按要求排序后的结果。
这题要求从小到大排序,所以我们比较函数也不需要写,只需要一个sort就能搞定了:
#include<algorithm>
#include<iostream>
using namespace std;
int main(){
int n;
cin >> n;
float grd[n + 1];
for(int i = 1; i <= n; i++){
cin >> grd[i];
}
sort(grd + 1, grd + 1 + n);//注意这里的下标是从1开始的
for(int i = 1; i <= n; i++){
cout << grd[i] << endl;
}
return 0;
}
之后再看看下面这个题:
身高排序
Description
有 n 个同学排成一排,从左到右依次编号为 1~n。
现在给出了这个 n 位同学的身高,但是并不是按照高矮排序的。现在这些同学需要按照身高从矮到高的顺序重新排列,矮的同学在左边,高的同学在右边。如果两个同学身高相同,那么这两个同学的相对顺序不应该发生变化。
请你输出排序以后从左到右同学的编号。
Input
输入一个行一个整数 n(1≤n≤1000)。
接下来一行输入 n 个整数,依次表示从左到右的同学的身高,每个同学身高小于等于 300。
Output
一行输出 n 个整数,两个数中间用空格隔开,行末不要有多余空格。
表示重新排列以后从左到右的同学的编号。
这题也简单,只需要将学生的编号和身高用一个结构体包装起来然后排序就可以了。不过排序时需要按照身高来排序,怎么实现让sort按照身高来排序呢?
接着我们之前讲到的比较函数,这题用比较函数来解就很简单了。这里的比较函数写法如下:
首先定义一个结构体:
struct node{
int id, h;
}stu[1000 + 5];
然后写出比较函数:
bool cmp(const node &x, const node &y){
return x.h < y.h;
}
做完这些,我们就可以写下sort函数了。完整代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
int id;
int h;
};
bool cmp(const node &x, const node &y){
return x.h < y.h;
}
int main(){
int n;
cin >> n;
node stu[n + 1];
for (int i = 1; i <= n; i++){
stu[i].id = i;
cin >> stu[i].h;
}
sort (stu + 1, stu + n + 1, cmp);
bool flag = 0;
for (int i = 1; i <= n; i++){
if(i != 1) cout << " ";
cout << stu[i].id;
}
return 0;
}
不过在经过几组数据的测试之后,却发现了这样的问题:有时身高相同时,对应学生的编号却改变了(原本不应该改变)。对于这个问题,我们调用一个稳定的排序函数:stable_sort()。只需要将原来的sort替换掉就可以了:
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
int id;
int h;
};
bool cmp(const node &x, const node &y){
return x.h < y.h;
}
int main(){
int n;
cin >> n;
node stu[n + 1];
for (int i = 1; i <= n; i++){
stu[i].id = i;
cin >> stu[i].h;
}
stable_sort (stu + 1, stu + n + 1, cmp);
bool flag = 0;
for (int i = 1; i <= n; i++){
if(i != 1) cout << " ";
cout << stu[i].id;
}
return 0;
}
单词排序
Description
小红学会了很多英文单词,妈妈为了帮小红加强记忆,拿出纸、笔,把 N 个单词写在纸上的一行里,小红看了几秒钟后,将这张纸扣在桌子上。妈妈问小红:“你能否将这 N 个单词按照字典排列的顺序,从小到大写出来?”小红按照妈妈的要求写出了答案。现在请你编写程序帮助妈妈检查小红的答案是否正确。注意:所有单词都由小写字母组成,开头字母全都不相同,单词两两之间用一个空格分隔。
Input
输入包含两行。
第一行仅包括一个正整数 N(0<N≤26)。
第二行包含 N 个单词,表示妈妈写出的单词,两两之间用一个空格分隔。单个单词长度不超过 10。
Output
输出仅有一行——针对妈妈写出的单词,按照字典排列的顺序从小到大排列成一行的结果,单词两两之间用一个空格分隔。
这题也是只需要调用sort函数就可以了,因为sort函数在对字符排序时是按照字典序的。代码如下:
#include<algorithm>
#include<iostream>
using namespace std;
int main(){
int n;
cin >> n;
string word[n];
for(int i = 0; i < n; i++) cin >> word[i];
sort(word, word + n);
for(int i = 0; i < n; i++){
if(i) cout << " ";
cout << word[i];
}
cout << endl;
return 0;
}
Share
玩具排序
Description
小信有 N 个毛绒玩具,小信给他们都起了名字,每个毛绒玩具的名字长度不定。小信现在已不满足于玩具本身带来的乐趣了,他突发奇想,想把每个玩具的名字倒过来,再按照倒过来的名字给玩具排个序,看这些毛绒玩具的摆放顺序是怎样的。小信特别喜欢跟朋友一起玩耍,现在他想要你帮他把这个事情完成。
Input
输入第一行是一个整数 N (0<N≤30)表示小蒜的毛绒玩具数。
之后的 N 行,每行有一个字符串,是小蒜的某一个毛绒玩具的名称。
Output
输出有 N 行,是所有毛绒玩具倒过来后的“名字”按照字典序排序后的结果。
这题同样的需要调用sort函数,只是这里多了将字符串逆转过来的操作:
#include<algorithm>
#include<iostream>
using namespace std;
int main(){
int n;
cin >> n;
string toy[n];
for(int i = 0; i < n; i++) cin >> toy[i];
for(int i = 0; i < n; i++){
string buff;
int d = 0;
while(d < toy[i].size()){
buff+= toy[i][toy[i].size() - d - 1];
d++;
}
toy[i] = buff;
}//将字符串翻转过来
sort(toy, toy + n);
for(int i = 0; i < n; i++) cout << toy[i] << endl;
return 0;
}
分数线
Description
某小学举办了一场校内的信息学竞赛选拔赛。赛后几天之后,同学们的成绩都出来了。现在负责信息学竞赛的老师需要确定最终选拔赛的获奖名单。为了鼓励大家,老师希望获奖人数不少于参赛总人数的一半。因此,老师需要确定一个获奖分数线,所有得分在分数线及以上的同学可以获奖。在满足上面条件的情况下,老师希望获奖分数线越高越好。
请同学们通过程序设计的方法来解决以上问题,确定获奖分数线和总获奖人数。
Input
第一行为一个整数 n 表示参赛总人数。
第二行为 n 个整数,分别表示 n(1≤n≤100000) 个参赛同学的分数,所有分数都是在 0~100 之间的整数(含 0 和 100),每两个数之间用一个空格隔开。
Output
为一行,包括两个整数分别表示分数线和获奖人数(中间用一个空格隔开)。
读完题目,我们可以看出这题只需要对数组进行排序,然后中间同学的分数就是所求的分数线了。至于获奖人数,由于前面已经从大到小排过序,所以我们从第一个下标开始向后寻找,当寻找到第一个与分数线相同的学生时,退出循环,获奖人数就等于总人数减去此时的下标再加一。代码如下:
#include<algorithm>
#include<iostream>
using namespace std;
int main(){
int n;
cin >> n;
int grade[n + 1];
for(int i = 1; i <= n; i++) cin >> grade[i];
sort(grade + 1, grade + n + 1);
int ans1, ans2;
ans1 = grade[n / 2 + 1];
int i;
for(i = 1; i <= n; i++){
if(grade[i] == ans1){
ans2 = n - i + 1;
break;
}
}
cout << ans1 << " " << ans2 << endl;
return 0;
}
成绩排序
Description
小信所在的学校一开学就进行了一次摸底考试。摸底考试考了语文、数学、英语、科学共四门课程。
小信的老师汇总成绩后列出了成绩单,其中包括每个同学的姓名和四科的成绩。现在老师希望表扬一下每门课程考试得分前四名和总分前四名的同学,同分数的情况下,名字字典序更小的先表扬。
请你帮助老师写一个程序,快速完成这件事情吧。
Input
第一行为学生人数 N(4≤N≤100)。之后 N 行依次为每个学生的姓名和语文、数学、英语、科学这四门课程的成绩,之间用一个空格隔开(成绩都大于等于 0 小于等于 100)。
Output
输出第一行为语文考试要表扬前四名的同学的姓名,之间用一个空格隔开(行尾没有空格)。
输出第二行为数学考试要表扬前四名的同学的姓名,之间用一个空格隔开(行尾没有空格)。
输出第三行为英语考试要表扬前四名的同学的姓名,之间用一个空格隔开(行尾没有空格)。
输出第四行为科学考试要表扬前四名的同学的姓名,之间用一个空格隔开(行尾没有空格)。
输出第五行为总分要表扬前四名的同学的姓名,之间用一个空格隔开(行尾没有空格)。
看到这么多数据,我们很自然地想到用结构体将它们包装起来,然后对语文、数学、英语、科学成绩和总分分别排一次序,再输出名字就可以了:
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn = 10000 + 5;
struct node{
string name;
int a, b, c, d, sum;
}stu[maxn];
bool cmpa(const node x, const node y){
if(x.a != y.a) return x.a > y.a;
return x.name < y.name;
}
bool cmpb(const node x, const node y){
if(x.b != y.b) return x.b > y.b;
return x.name < y.name;
}
bool cmpc(const node x, const node y){
if(x.c != y.c) return x.c > y.c;
return x.name < y.name;
}
bool cmpd(const node x, const node y){
if(x.d != y.d) return x.d > y.d;
return x.name < y.name;
}
bool cmps(const node x, const node y){
if(x.sum != y.sum) return x.sum > y.sum;
return x.name < y.name;
}
int main(){
int n;
cin >> n;
for(int i = 1; i <= n; i++){
cin >> stu[i].name >> stu[i].a >> stu[i].b >> stu[i].c >> stu[i].d;
stu[i].sum = stu[i].a + stu[i].b + stu[i].c + stu[i].d;
}
stable_sort(stu + 1, stu + 1 + n, cmpa);
bool flag = 0;
for(int i = 1; i <= 4; i++){
if(i != 1) cout << " ";
cout << stu[i].name;
}
flag = 0;
cout << endl;
stable_sort(stu + 1, stu + 1 + n, cmpb);
for(int i = 1; i <= 4; i++){
if(i != 1) cout << " ";
cout << stu[i].name;
}
flag = 0;
cout << endl;
stable_sort(stu + 1, stu + 1 + n, cmpc);
for(int i = 1; i <= 4; i++){
if(i != 1) cout << " ";
cout << stu[i].name;
}
flag = 0;
cout << endl;
stable_sort(stu + 1, stu + 1 + n, cmpd);
for(int i = 1; i <= 4; i++){
if(i != 1) cout << " ";
cout << stu[i].name;
}
flag = 0;
cout << endl;
stable_sort(stu + 1, stu + 1 + n, cmps);
for(int i = 1; i <= 4; i++){
if(i != 1) cout << " ";
cout << stu[i].name;
}
cout << endl;
return 0;
}