寒假学习c++第一弹——sort排序练习(2021.01.18)

sort排序练习

目录

1.浮点数排序

2.分数线

3.交叉排序

4.红绿蓝

5.整数排序进阶

6.成绩排序

7.成绩排序升级版

8.抢气球

9.抢气球升级版


 1.浮点数排序

题目描述:

我们有N个正浮点数,均小于10000.0。现在需要将这些浮点数按照离它最近的整数的差从小到大排序,浮点数与距离最近的整数的差越小,这个浮点数的排位越靠前;  如果差相等,按照浮点数的值从小到大排序。

判断浮点数相等应使用如下语句:

if(fabs(a-b) < EPSILON){
    //执行当两个浮点数a和b相等时的操作
}

其中EPSILON为常量,大小为10^-6。

输入格式:

输入有两行:第一行为一个整数N,0<N<101; 第二行为用空格隔开的N个浮点数,均小于10000.0.

输出格式:

输出有一行,为按照题目要求排序后的N个正浮点数,四舍五入保留6位小数,用空格隔开。

样例输入

9

1.001   2.1   3.2   4.0001   5.000001   6.9   7.2   8.001   9.0

样例输出

9.000000   5.000001   4.000100   1.001000   8.001000   2.100000   6.900000   3.200000   7.200000

代码如下 

#include <iostream>
#include <algorithm>
#include <iomanip>
#include <cmath>
using namespace std;
const double EPSILON = 1e-6;
double num[105];
bool cmp(double a, double b){
    double da = fabs(a - round(a));  //round函数对浮点数四舍五入
    double db = fabs(b - round(b));  //fabs函数取绝对值
    if(fabs(da - db) < EPSILON){
        return a < b;
    }
    return da < db;
}
int main(){
    int N;
    cin >> N;
    for(int i = 0; i < N; i++){
        cin >> num[i];
    }
    sort(num, num+N, cmp);
    for(int i = 0; i < N; i++){
        if(i != N - 1){
            cout << fixed << setprecision(6) << num[i] << " ";  //保留六位小数输出,头文件iomanip
        }else{
            cout << fixed << setprecision(6) << num[i] << endl;
        }
    }
    return 0;
}

2.分数线

题目描述:

某小学举办了一场校内的信息学竞赛选拔赛。现在同学们的成绩都出来了,负责信息学竞赛的老师需要确定最终选拔赛的获奖名单。为了鼓励大家,老师希望获奖人数不少于参赛总人数的一半。因此,老师需要确定一个获奖分数线,所有得分在分数线及以上的同学可以获奖。在满足上面条件的情况下,老师希望获奖分数线越高越好。请同学们通过程序设计的方法来解决以上问题,确定获奖分数线和总获奖人数。

输入格式:

第一行为一个整数n表示参赛总人数。第二行位n个整数,分别表示n(1<=n<=100000)个参赛同学的分数,所有分数都是在0-100之间的整数(含0和100),每两个数之间用一个空格隔开。

输出格式:

输出为一行,包括两个整数,分别表示分数线和获奖人数(中间用一个空格隔开)。

样例输入

7

76   71   42   4   27   27   20

样例输出

27   5

代码如下

#include <iostream>
#include <algorithm>
int score[100005];
using namespace std;
int main(){
    int n;
    int cnt = 0;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> score[i];
    }
    sort(score, score+n, greater<int>());  //降序排序
    cout << score[(n - 1) / 2] << " ";
    for(int i = 0; i < n; i++){
        if(score[i] >= score[(n - 1) / 2]){
            cnt++;
        }else{
            break;
        }
    }
    cout << cnt << endl;
    return 0;
}

3.交叉排序

题目描述:

 我们有N个数,先将数组中第l1到第r1的数字按从小到大的顺序排序。再将数组中第l2到第r2的数字按从大到小的顺序排序,求排序的结果。

输入格式:

第一行五个整数N,l1,r1,l2,r2,其中0< l1< r1< N,这五个数不超过10000;第二行为N个整数。

输入样例:

6   1   3   2   4

8   3   1   6   9   2

输出样例:

1   8   6   3   9   2

代码如下

#include <iostream>
#include <algorithm>
using namespace std;
int num[10005];
int main(){
    int N, l1, r1, l2, r2;
    cin >> N >> l1 >> r1 >> l2 >> r2;
    for(int i = 0; i < N; i++){
        cin >> num[i];
    }
    sort(num + l1 - 1, num + r1);
    sort(num + l2 - 1, num + r2, greater<int>());
    for(int i = 0; i < N; i++){
        if(i != N - 1){
            cout << num[i] << " ";
        }else{
            cout << num[i] << endl;
        }
    }
    return 0;
}

4.红绿蓝

题目描述:

有一个罐子,里面装着红的、绿的、蓝的玻璃珠子若干,分别用R、G、B表示。我希望把它们排成一行,并按照字典序排列(即 B->G->R的顺序)。然后以一红二绿三蓝为一组串成一串幸运珠,多余的放回罐子里,那么我能串成多少串幸运珠呢?

输入格式:

输入为一行,是一个由若干个R、G、B乱序组成的字符串,长度小于10000,每个字母至少出现一次。

输出格式:

输出共2行;第一行是排序完成后的字符串;第二行是一个整数,为串成的幸运珠的数目。

输入样例:

RGGBBB

输出样例:

BBBGGR

1

代码如下

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
char s[10005];
int main(){
    int len, r = 0, g = 0, b = 0;
    cin >> s;
    len = strlen(s);
    sort(s, s+len);
    cout << s << endl;
    //最小限制条件
    for(int i = 0; i < len; i++){
        if(s[i] == 'R'){
            r++;
        }else if(s[i] == 'G'){
            g++;
        }else{
            b++;
        }
    }
    cout << min(r, min(g / 2, b / 3)) << endl;
    return 0;
}

5.整数排序进阶

题目描述:

有N个正整数,均小于10000.现在需要将这些正整数按该正整数每一位数字相加的和从小到大排序,即该正整数的每一位数字相加的和越小排位越靠前。如果各位相加和相等,则按照正整数的值从小到大排序。

输入格式:

输入有两行,第一行为一个整数N,0<N<101;第二行位用空格隔开的N个正整数,均小于10000。

输出格式:

输出有一行,为按照题目要求排序后的N个正整数,用空格隔开。

输入样例:

4

20   12   1   11

输出样例:

1   11   20   12

代码如下

#include <iostream>
#include <algorithm>
using namespace std;
int num[105];
bool cmp(int a, int b){
    int aa = a, bb = b;
    int suma = 0, sumb = 0;
    while(a){
        suma += a % 10;
        a /= 10;
    }
    while(b){
        sumb += b % 10;
        b /= 10;
    }
    if(suma == sumb){
        return aa < bb;
    }
    return suma < sumb;
}
int main(){
    int N;
    cin >> N;
    for(int i = 0; i < N; i++){
        cin >> num[i];
    }
    sort(num, num+N, cmp);
    for(int i = 0; i < N; i++){
        if(i != N - 1){
            cout << num[i] << " ";
        }else{
            cout << num[i] << endl;
        }
    }
    return 0;
}

6.成绩排序

题目描述:

班上有n个同学编号为1-n,每个同学有一个分数。现在他请你帮忙做一份全班同学的成绩排名表。首先你需要按照分数从高到低将所有同学排序,再输出成绩单上每个同学的编号,保证任意两个同学的分数互不相同。

输入格式:

输入共有两行,第一行为学生人数n(4 <= n <= 100).接下来一行n个整数ai(1 <= ai <= 100),分别表示每个同学的分数。

输出格式:

输出共一行,为n个用空格隔开的整数,分别表示成绩排名第1,2,3,......,n同学的编号。

输入样例:

5

97

68

51

85

73

输出样例:

1   4   5   2   3

代码如下

#include <iostream>
#include <algorithm>
using namespace std;
struct Student{
    int score;
    int id;
};
bool cmp(Student x, Student y){
    return x.score > y.score;
}
Student stu[105];
int main(){
    int n;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> stu[i].score;
        stu[i].id = i + 1;
    }
    sort(stu, stu+n, cmp);
    for(int i = 0; i < n; i++){
        if(i != n - 1){
            cout << stu[i].id << " ";
        }else{
            cout << stu[i].id << endl;
        }
    }
    return 0;
}

7.成绩排序升级版

题目描述:

学校进行了摸底考试,考了语文、数学、英语、科学共四门课程。老师汇总成绩后列出了成绩单,其中包括每个同学的姓名和四科的成绩。老师希望表扬一下每门课程得分前四名和总分前四名的同学,同分数的情况下,名字字典序更小的先表扬。请你帮助老师快速找出要表扬的同学。

输入格式:

第一行为学生人数N(4 <= N <= 100)。之后N行依次为每个学生的姓名和语文、数学、英语、科学这四门课的成绩,之间用一个空格隔开(成绩都大于等于0小于等于100).

输出格式:

输出第一行为语文考试表扬的前四名学生姓名,之间用一个空格隔开。第二行为数学考试表扬的前四名学生姓名,之间用一个空格隔开。第三行为英语考试表扬的前四名学生姓名,之间用一个空格隔开。第四行为科学考试表扬的前四名学生姓名,之间用一个空格隔开。第五行为总分语文表扬的前四名学生姓名,之间用一个空格隔开。

输入样例:

5

Alice 99 98 97 96

Bob 98 97 96 94

Coy 94 94 95 96

Dan 93 95 96 97

Evan 0 94 95 95

输出样例:

Alice Bob Coy Dan

Alice Bob Dan Coy

Alice Bob Dan Coy

Dan Alice Coy Evan

Alice Bob Dan Coy

代码如下

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
struct Student{
    char name[105];
    int score[4];
};
Student stu[105];
//语文成绩比较
bool cmp1(Student a, Student b){
    if(a.score[0] != b.score[0]){
        return a.score[0] > b.score[0];
    }
    return strcmp(a.name, b.name) < 0;  //小于0,a小,大于0,b小
}
//数学
bool cmp2(Student a, Student b){
    if(a.score[1] != b.score[1]){
        return a.score[1] > b.score[1];
    }
    return strcmp(a.name, b.name) < 0;  //小于0,a小,大于0,b小
}
//英语
bool cmp3(Student a, Student b){
    if(a.score[2] != b.score[2]){
        return a.score[2] > b.score[2];
    }
    return strcmp(a.name, b.name) < 0;  //小于0,a小,大于0,b小
}
//科学
bool cmp4(Student a, Student b){
    if(a.score[3] != b.score[3]){
        return a.score[3] > b.score[3];
    }
    return strcmp(a.name, b.name) < 0;  //小于0,a小,大于0,b小
}
//总分
bool cmp5(Student a, Student b){
    int suma = 0, sumb = 0;
    for(int i = 0; i < 4; i++){
        suma += a.score[i];
        sumb += b.score[i];
    }
    if(suma != sumb){
        return suma > sumb;
    }
    return strcmp(a.name, b.name) < 0;  //小于0,a小,大于0,b小
}
void print(){
    for(int i = 0; i < 3; i++){
        cout << stu[i].name << " ";
    }
    cout << stu[3].name << endl;
}
int main(){
    int n;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> stu[i].name;
        for(int j = 0; j < 4; j++){
            cin >> stu[i].score[j];
        }
    }
    sort(stu, stu+n, cmp1);
    print();
    sort(stu, stu+n, cmp2);
    print();
    sort(stu, stu+n, cmp3);
    print();
    sort(stu, stu+n, cmp4);
    print();
    sort(stu, stu+n, cmp5);
    print();
}

8.抢气球

题目描述:

教室的墙上挂满了气球,五颜六色,小朋友们非常喜欢。刚一下课,小朋友们就打算去抢这些气球。每个气球在墙上都有一定的高度,只有当小朋友跳起来时,手能够到的高度大于等于气球的高度,小朋友才能摘到这个气球。为了公平起见,老师让跳的低的小朋友先摘,跳的高的小朋友后摘。小朋友都很贪心,每个小朋友在摘气球的时候都会把自己能摘的气球都摘掉。很巧的是,小朋友们跳起来手能够着的高度都不一样,这样就不会有跳起来后高度相同的小朋友之间发生争执了。

输入格式:

第一行输入两个空格分隔的整数n,m(1 <= n, m <= 1000),其中n表示小朋友的数量,m表示墙上的气球个数。第二行输入n个正整数,第i个数为ai(1 <= ai <= 10^5),表示第i个小朋友跳起来手能够到的高度ai;第三行输入m个正整数,第i个数为hi(1 <= hi <= 10^5),表示第i个气球的高度hi。

输出格式:

输出共n行,每行一个整数,第i行表示第i个小朋友摘到的气球数量。

输入样例:

5   6

3   7   9   6   4

1   2   3   4   5   6

输出样例:

3

0

0

2

1

代码如下

#include <iostream>
#include <algorithm>
using namespace std;
struct Children{
    int a;
    int id;
};
bool cmp(Children a, Children b){
    return a.a < b.a;
}
Children child[1005];
int h[1005];
int ans[1005]; //记录小朋友摘到的数量
bool used[1005]; //判断气球是否被摘走
int main(){
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < n; i++){
        cin >> child[i].a;
        child[i].id = i;
    }
    for(int i = 0; i < m; i++){
        cin >> h[i];
    }
    sort(child, child+n, cmp);
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(!used[j] && h[j] <= child[i].a){
                ans[child[i].id]++;
                used[j] = true;
            }
        }
    }
    for(int i = 0; i < n; i++){
        cout << ans[i] << endl;
    }
    return 0;
}

9.抢气球升级版

题目描述:

教室的墙上挂满了气球,五颜六色,小朋友们非常喜欢。刚一下课,小朋友们就打算去抢这些气球。每个气球在墙上都有一定的高度,只有当小朋友跳起来时,手能够到的高度大于等于气球的高度,小朋友才能摘到这个气球。为了公平起见,老师让跳的低的小朋友先摘,跳的高的小朋友后摘。小朋友都很贪心,每个小朋友在摘气球的时候都会把自己能摘的气球都摘掉。很巧的是,小朋友们跳起来手能够着的高度都不一样,这样就不会有跳起来后高度相同的小朋友之间发生争执了。

输入格式:

第一行输入两个空格分隔的整数n,m(1 <= n, m <= 10^5)(发生改变),其中n表示小朋友的数量,m表示墙上的气球个数。第二行输入n个正整数,第i个数为ai(1 <= ai <= 10^9)(发生改变),表示第i个小朋友跳起来手能够到的高度ai;第三行输入m个正整数,第i个数为hi(1 <= hi <= 10^9)(发生改变),表示第i个气球的高度hi。

输出格式:

输出共n行,每行一个整数,第i行表示第i个小朋友摘到的气球数量。

输入样例1:

5   6

3   7   9   6   4

1   2   3   4   5   6

输出样例1:

3

0

0

2

1

输入样例2:

10   10

1   2   3   4   5   6   7   8   9   10

3   1   4   6   7   8   9   9   4   12

输出样例2:

1

0

1

2

0

1

1

1

2

0

代码如下

#include <iostream>
#include <algorithm>
using namespace std;
//把气球也排序
struct Children{
    int a;
    int id;
};
bool cmp(Children a, Children b){
    return a.a < b.a;
}
Children child[1005];
int h[1005];
int ans[1005]; //记录小朋友摘到的数量
int main(){
    int n, m, p;
    cin >> n >> m;
    for(int i = 0; i < n; i++){
        cin >> child[i].a;
        child[i].id = i;
    }
    for(int i = 0; i < m; i++){
        cin >> h[i];
    }
    sort(child, child+n, cmp);
    sort(h, h+m);
    p = 0; //用来记录上个小朋友摘到哪里了
    for(int i = 0; i < n; i++){
        while(p < m && h[p] <= child[i].a){
            ans[child[i].id]++;
            p++;
        }
    }
    for(int i = 0; i < n; i++){
        cout << ans[i] << endl;
    }
    return 0;
}

如有错误欢迎指正。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值