zoukankan      html  css  js  c++  java
  • 蓝桥杯省赛备战笔记—— (四)使用sort排序——练习题

     例题:浮点数排序

     

     

    #include<stdio.h>
    #include<math.h>
    #include<iostream>
    #include<algorithm>
    #define EPSILON 1e-6
    using namespace std;
    double s[105];
    bool cmp(double a,double b){
        double aa = fabs(a - round(a));
        double bb = fabs(b - round(b));
        if(fabs(aa - bb) < EPSILON){
            return a < b;
        } //如果两个浮点数的与最近整数的差 相差小于指定的值,就认为两差数大小相等,当两差数大小相等时,就按原来的浮点数的值从小到大排序
        return aa < bb;    //否则,按照两差数 从小到大排序
    }
    int main(){int n;
        double x; 
        scanf("%d",&n);
        for(int i = 0;i < n;i++){
            scanf("%lf",&s[i]);
        }
        sort(s,s+n,cmp);
        for(int i  =0; i < n;i++){
            if(i == 0){
                printf("%.6f",s[i]);
            }else{
                printf(" %.6f",s[i]);
            }
        }
        
        return 0;
    }
    • fabs()   —— 对浮点数求绝对值
    • round() —— 四舍五入的整数,相当于是最近的整数

    例题:分数线

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

    输入格式:

     

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int s[10005];
    int main(){
        int n;
        scanf("%d",&n);
        for(int i= 0; i< n;i++){
            scanf("%d",&s[i]);    
        }
        sort(s,s+n,greater<int>());
        int x= s[(n-1)/2];
        printf("%d ",x);
        int sum = 0;
        for(int i = 0;i < n;i++){
            if(s[i] >= x)
                sum++;
            else
                break;
        }
        printf("%d",sum);
        return 0;
    }

    例题:交叉排序

    蒜头君很无聊,他想对数组中的某些元素进行排
    序。
    现在我们有N个数,他想先将数组中第l1到第r1
    的数字按从小到大的顺序排序。再将数组中第l2
    到第r2的数字按从大到小的顺序排序。
    我们帮他算一算数组排序后的结果吧~

     

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int a[10005];
    int main(){
        int n,l1,r1,l2,r2;
        scanf("%d%d%d%d%d",&n,&l1,&r1,&l2,&r2);
        for(int i = 0;i < n;i++){
            scanf("%d",&a[i]);
        }
        sort(a + l1 - 1,a + r1 );
        sort(a + l2- 1, a + r2,greater<int>());
        for(int i = 0;i < n;i++){
            if(i == 0)
                printf("%d",a[i]);
            else
                printf(" %d",a[i]);
        }
        return 0;
    }

    例题:红绿蓝

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

    #include<stdio.h>
    #include<algorithm>
    #include<iostream>
    #include<string.h>
    #include<math.h>
    using namespace std;
    char s[10005];
    int main(){
        scanf("%s",s);
        int len = strlen(s);
        sort(s,s+len);
        printf("%s
    ",s);
        int r = 0;
        int g = 0;
        int b = 0;
        for(int i =0 ;i < len;i++){
            if(s[i] == 'R')
                r++;
            else if (s[i] == 'G')
                g++;
            else
                b++;
        }
        int mi = min(r,min(g/2,b/3));
        printf("%d",mi);
        return 0;
    }

     例题:整数排序进阶

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

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int s[105];
    bool cmp(int a,int b){
        int aa = a;
        int bb = b;
        int suma = 0;
        int sumb = 0;
        while(a != 0){
            suma += a % 10;
            a /= 10;
        }
        while(b != 0){
            sumb += b % 10;
            b /= 10;
        }
        if(suma == sumb)
            return aa < bb;
        return suma < sumb;
    }
    int main(){
        int n;
        scanf("%d",&n);
        for(int i = 0; i< n;i++){
            scanf("%d",&s[i]);
        }
        sort(s,s+n,cmp);
        for(int i =0 ;i < n;i++){
            if( i == 0)
                printf("%d",s[i]);
            else
                printf(" %d",s[i]);
        }    
        return 0;
    }

     例题:成绩排序

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

     

    #include<stdio.h>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    struct Stu{
        int score;
        int id;
    };
    bool cmp(Stu x,Stu y){
        return x.score > y.score;
    }
    Stu stu[105];
    int main(){
        int n;
        scanf("%d",&n);
        for(int i = 0;i < n;i++){
            int a;
            scanf("%d",&a);
            stu[i].score = a;
            stu[i].id = i+1;
        }
        sort(stu,stu+n,cmp);
        for(int i  =0; i < n;i++){
            if(i == 0)
                printf("%d",stu[i].id);
            else
                printf(" %d",stu[i].id);
        }
        return 0;
    }

    例题:成绩排序升级版

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

    输入格式
    第一-行为学生人数N(4<= N ≤100)。
    之后N行依次为每个学生的姓名和语文、数学、
    英语、科学这四门课程的成绩,之间用一个空格隔
    开(成绩都大于等于0小于等于100)
    输出格式
    输出第一行为语文考试要表扬前四名的同学的姓
    名,之间用-一个空格隔开。

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

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    struct Stu{
        char name[10];
        int score[4];
    };
    Stu stu[105];
    void print(int n){
        n = n - 1;
        for(int i = 0; i < n;i++){
            if(i == 0)
                printf("%s",stu[i].name);
            else
                printf(" %s",stu[i].name);
        }
        printf("
    ");
    }
    bool cmp1(Stu a,Stu b){
        if(a.score[0] != b.score[0])
            return a.score[0] > b.score[0];
        return strcmp(a.name, b.name) < 0;  //strcmp(x,y). 如果字符串x 按字典序小于y,则返回小于0的值
        //如果为真,则 a 排在 b 前面  
    }
    bool cmp2(Stu a,Stu b){
        if(a.score[1] != b.score[1])
            return a.score[1] > b.score[1];
        return strcmp(a.name, b.name) < 0; 
    }
    bool cmp3(Stu a,Stu b){
        if(a.score[2] != b.score[2])
            return a.score[2] > b.score[2];
        return strcmp(a.name, b.name) < 0;  //strcmp(x,y). 如果字符串x 按字典序小于y,则返回小于0的值
        //如果为真,则 a 排在 b 前面  
    }
    bool cmp4(Stu a,Stu b){
        if(a.score[3] != b.score[3])
            return a.score[3] > b.score[3];
        return strcmp(a.name, b.name) < 0;  //strcmp(x,y). 如果字符串x 按字典序小于y,则返回小于0的值
        //如果为真,则 a 排在 b 前面  
    }
    bool cmp_all(Stu a,Stu b){
        int sum_a = 0;
        int sum_b = 0;
        for(int i = 0 ;i < 4;i++){
            sum_a += a.score[i];
            sum_b += b.score[i];
        }
        if(sum_a != sum_b)
            return sum_a > sum_b;
        return strcmp(a.name, b.name) < 0;  //strcmp(x,y). 如果字符串x 按字典序小于y,则返回小于0的值
        //如果为真,则 a 排在 b 前面  
    }
    int main(){
        int N;    
        scanf("%d",&N);
        for(int i =  0;i < N;i++){
            scanf("%s",stu[i].name);
            for(int j = 0;j < 4;j++){
                scanf("%d",&stu[i].score[j]);
            }
        }
        sort(stu,stu+N,cmp1);
        print(N);
        sort(stu,stu+N,cmp2);
        print(N);
        sort(stu,stu+N,cmp3);
        print(N);
        sort(stu,stu+N,cmp4);
        print(N);
        sort(stu,stu+N,cmp_all);
        print(N);
        return 0;
    }

    例题:抢气球

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

     样例2:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    struct Child{
        int id;
        int h;
    };
    Child ch[1005];
    int flag[1005];
    int child_get[1005];
    int ball_h[1005]; 
    
    bool cmp(Child x,Child y){
        return x.h < y.h;
    }
    int main(){
        int n,m;
        scanf("%d %d",&n,&m);
        for(int i = 0 ;i < n;i++){
            scanf("%d",&ch[i].h);
            ch[i].id = i;
        }
        for(int i = 0;i < m;i++){
            scanf("%d",&ball_h[i]);
        }
        sort(ch,ch+n,cmp);
        for(int i = 0; i < n;i++){
            for(int j = 0;j < m;j++){
                if(ball_h[j] <= ch[i].h && flag[j] == 0){//如果气球高度可以摘到,同时没有被摘下来
                    flag[j] = 1;
                    child_get[ch[i].id]++; //排序前的顺序
                }
            }
        }
        for(int i = 0 ;i < n;i++){
            printf("%d
    ",child_get[i]);
        }
        return 0;
    }

     例题:抢气球升级版

     只有n m 的规模发生了变化,增大到 10^ 5 级,时间限制1s ,显然,上方的做法会超时

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    struct Child{
        int id;
        int h;
    };
    Child ch[1005];
    int child_get[1005];
    int ball_h[1005]; 
    
    bool cmp(Child x,Child y){
        return x.h < y.h;
    }
    int main(){
        int n,m;
        scanf("%d %d",&n,&m);
        for(int i = 0 ;i < n;i++){
            scanf("%d",&ch[i].h);
            ch[i].id = i;
        }
        for(int i = 0;i < m;i++){
            scanf("%d",&ball_h[i]);
        }
        sort(ch,ch+n,cmp);
        
        //只需要将气球也按高度排序即可,优化内部for循环,省去扫描已经被摘走的气球
        sort(ball_h,ball_h + m);
        int p = 0; 
        for(int i = 0; i < n;i++){
             while(p < m && ball_h[p] <= ch[i].h ){
                 child_get[ch[i].id]++;
                p++;
             }
        }
        //时间复杂度 由O(n*m)--> O(n+m) 
        for(int i = 0 ;i < n;i++){
            printf("%d
    ",child_get[i]);
        }
        return 0;
    }
  • 相关阅读:
    COM组件开发实践(七)---多线程ActiveX控件和自动调整ActiveX控件大小(上)
    A Complete ActiveX Web Control Tutorial
    C++使用VARIANT实现二维数组的操作
    用户自定义结构数据与VARIANT转换
    VS2008中使用JSONCPP方法小结
    HDOJ 2030 汉字统计
    HDOJ 1312 (POJ 1979) Red and Black
    POJ 1503 Integer Inquiry 简单大数相加
    POJ 1936 All in All
    枚举法
  • 原文地址:https://www.cnblogs.com/expedition/p/12315215.html
Copyright © 2011-2022 走看看