Sort练习题

sort 练习

练习题

  1. 题目:浮点数排序

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <algorithm>    //sort()排序
#include <cmath>    //round()来找最近的整数
using namespace std;
const double EPSILON = 1e-6;    //两个浮点数的差小于该数则认为两数相等,1 * (10 ^ (-6))
double num[105];
//计算距离它最近的整数的差
double sub(double x)
{
    return fabs(x - round(x));  //不知道谁更大,用fabs取绝对值
}
bool cmp(double a, double b)
{
    if (fabs(sub(a) - sub(b)) < EPSILON)
    {   //差值相等,则用本身的值排序
        return a < b;
    }
    return sub(a) < sub(b);
}

int main()
{
    int N;
    scanf("%d", &N);
    for (int i = 0; i < N; i++)
    {
        scanf("%lf", &num[i]);
    }
    sort(num, num + N, cmp);
    for (int i = 0; i < N; i++)
    {
        if (i != (N - 1)) {
            //cout << num[i] << " ";
            printf("%lf ", num[i]); //%lf默认是保留六位,不需要加.6
        }
        else {
            //cout << num[i] << endl;
            printf("%lf\n", num[i]);
        }
    }
    return 0;
}
/*
输入:
9
1.001 2.1 3.2 4.0001 5.00001 6.9 7.2 8.001 9.0
输出:
9.000000 5.000010 4.000100 1.001000 8.001000 2.100000 6.900000 3.200000 7.200000
*/
  1. 取中位数之后,达到中位数的人可能很多,所以并不是简单的取前一半

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <algorithm>
using namespace std;
int score[100005];

int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &score[i]);
    }
    sort(score, score + n, greater<int>());
    printf("%d ", score[(n - 1) / 2]);
    int cnt = 0;
    for (int i = 0; i < n; i++)
    {
        if (score[i] >= score[(n - 1) / 2])
            cnt++;
        else
            break;
    }
    printf("%d\n", cnt);
    return 0;
}
/*
输入:
7
76 71 42 4 27 27 20
输出:
27 5
*/
  1. 交叉排序
    在这里插入图片描述

    #define _CRT_SECURE_NO_WARNINGS
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    int num[10005];
    
    int main()
    {
        int N, l1, l2, r1, r2;
        scanf("%d%d%d%d%d", &N, &l1, &r1, &l2, &r2);
        for (int i = 0; i < N; i++)
        {
            scanf("%d", &num[i]);
        }
        //第l1个下标是l1-1,第r1下标是r1-1
        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)
                printf("%d ", num[i]);
            else
                printf("%d\n", num[i]);
        }
        return 0;
    }
    /*
    输入:
    6 1 3 2 4
    8 3 1 6 9 2
    输出:
    1 8 6 3 9 2
    */
    
  2. 排序之后统计,注意求char数组这种C风格字符串的长度要用strlen(),min虽然只能求两个数中间较小的,但嵌套就能求三个数

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <algorithm>    //sort, min
#include <cstring>  //strlen

using namespace std;
char s[10005];

int main()
{
    int len, r = 0 ,g = 0, b = 0;
    scanf("%s", s);
    len = strlen(s);
    sort(s, s + len);
    printf("%s\n", s);
    for (int i = 0; i < len; i++)
    {
        if (s[i] == 'R')
            r++;
        else if (s[i] == 'G')
            g++;
        else
            b++;
    }
    printf("%d\n", min(min(r, g / 2), b / 3));
    return 0;
}
/*
输入:
RGGBBB
输出:
BBBGGR
1
*/
  1. 计算数据各位之和

    #define _CRT_SECURE_NO_WARNINGS
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    int num[105];
    int sumX(int a)
    {
        int ans = 0;
        while (a)
        {
            ans += a % 10;
            a /= 10;
        }
        return ans;
    }
    bool cmp(int a, int b)
    {
        if (sumX(a) == sumX(b))
        {
            return a < b;
        }
        return sumX(a) < sumX(b);
    }
    
    int main()
    {
        int N;
        scanf("%d", &N);
        for (int i = 0; i < N; i++)
            scanf("%d", &num[i]);
        sort(num, num + N, cmp);
        for (int i = 0; i < N; i++)
        {
            if (i != N - 1)
                printf("%d ", num[i]);
            else
                printf("%d\n", num[i]);
        }
        return 0;
    }
    /*
    输入:
    4
    20 12 1 11
    输出:
    1 11 20 12
    */
    
  2. 使用结构体

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <algorithm>
using namespace std;
/*
输入学生人数和每个学生的分数
输出成绩排名的学生编号
*/
struct Student
{
    int score;
    int id;
};
bool cmp(Student a, Student b)
{
    return a.score > b.score;
}
Student stu[105];

int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &stu[i].score);
        stu[i].id = i + 1;
    }
    sort(stu, stu + n, cmp);
    for (int i = 0; i < n; i++)
    {
        if (i != n - 1)
            printf("%d ", stu[i].id);
        else
            printf("%d\n", stu[i].id);
    }
    return 0;
}
/*
输入:
5
97
68
51
85
73
输出:
1 4 5 2 3
*/
  1. 稍微麻烦一些,对于字符串,string定义的话,是不可以用scanf和printf的。

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
using namespace std;
struct Student
{
    //没说学生姓名的长度,所以最好不要用char数组,用string
    string name;
    //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 a.name < b.name;
    //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 a.name < b.name;
}
bool cmp3(Student a, Student b)
{
    if (a.score[2] != b.score[2])
        return a.score[2] > b.score[2];
    return a.name < b.name;
}
bool cmp4(Student a, Student b)
{
    if (a.score[3] != b.score[3])
        return a.score[3] > b.score[3];
    return a.name < b.name;
}
bool cmp(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 a.name < b.name;
}

void print()
{
    for (int i = 0; i < 3; i++)
    {
        cout << stu[i].name << " ";
    }
    cout << stu[3].name << endl;
}

int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        cin >> stu[i].name;
        //scanf("%s", stu[i].name);   //输入字符数组不需要&
        for (int j = 0; j < 4; j++)
            scanf("%d", &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, cmp);
    print();
    return 0;
}
/*
输入:
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
*/
  1. 抢气球

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct Kid
{
    int a;  //高度
    int id;
};

int ans[1005];
Kid k[1005];
int h[1005];    //  气球高度
int used[1005]; //  是否被摘过

bool cmp(Kid x, Kid y)
{
    return x.a < y.a;
}

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &k[i].a);
        k[i].id = i;
    }
    for (int i = 0; i < m; i++)
    {
        scanf("%d", &h[i]);
    }
    sort(k, k + n, cmp);
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (!used[j] && h[j] <= k[i].a)
            {
                ans[k[i].id]++;
                used[j] = true;
            }
        }
    }
    for (int i = 0; i < n; i++)
    {
        printf("%d\n", ans[i]);
    }
    return 0;
}
/*
输入:
10 10
1 2 3 4 5 6 7 8 9 10
3 1 4 6 7 8 9 9 4 12
输出:
1
0
1
2
0
1
1
1
2
0
*/
//时间复杂度:O(nm)
  1. 将上面的题改为 1 ≤ n , m ≤ 1 0 5 1 \leq n,m \leq 10^5 1n,m105

    机器一秒钟可能运行 1 0 8 10^8 108,所以上面那种不可行

    其实每一个孩子并不需要考虑全部的气球,只需要把气球也排序,这样前面的孩子能摘得,后面的孩子就不能摘了。

    #define _CRT_SECURE_NO_WARNINGS
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    struct Children
    {
        int a;
        int id;
    };
    bool cmp(Children x, Children y)
    {
        return x.a < y.a;
    }
    Children child[100005];
    int h[100005];
    int ans[100005];
    
    int main()
    {
        int n, m, p = 0;    //p用来记录上一个孩子摘到哪个了
        scanf("%d%d", &n, &m);
        for (int i = 0; i < n; i++)
        {
            scanf("%d", &child[i].a);
            child[i].id = i;
        }
        for (int i = 0; i < m; i++)
        {
            scanf("%d", &h[i]);
        }
        sort(child, child + n, cmp);
        sort(h, h + m); //为气球排序
        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++)
        {
            printf("%d\n", ans[i]);
        }
        return 0;
    }
    //max{O(nlog(n)),O(mlog(m)),O(n+m)}
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值