算法学习——排序(2)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Marilynmontu/article/details/82025014

问题 E: Problem B
时间限制: 1 Sec 内存限制: 32 MB

题目描述
请写一个程序,对于一个m行m列的(1< m <10)的方阵,求其每一行,每一列及主对角线元素之和,最后按照从大到小的顺序依次输出。

输入
共一组数据,输入的第一行为一个正整数,表示m,接下来的m行,每行m个整数表示方阵元素。

输出
从大到小排列的一行整数,每个整数后跟一个空格,最后换行。

样例输入
4
15 8 -2 6
31 24 18 71
-3 -9 27 13
17 21 38 69

样例输出
159 145 144 135 81 60 44 32 28 27

解题思路
(1)计算待排序数组
(2)运用sort函数进行排序
注意:多组输入时一定要初始化存放待排序序列的数组。

Submission

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main(){
    int i, j, k, m;
    int x;
    while(scanf("%d", &m)!=EOF){
    int sum[30]={0};
    for( i=0; i<m; i++){
        for( j=0; j<m; j++){
            scanf("%d", &x);
            sum[i] = sum[i] + x;//计算每一行的和 
            sum[m+j] = sum[m+j] + x;//计算每一列的和 
            if( i == j ){
                sum[2*m] = sum[2*m] + x;//计算对角线的和
            }
            if( i == m-j-1 ){
                sum[2*m+1] = sum[2*m+1] + x;
            }
        }
    }
    sort(sum, sum+2*m+2);
    for(i=2*m+1; i>=0; i--)
    printf("%d ", sum[i]);
    printf("\n");       
    }
    return 0;
}    

问题 F: 小白鼠排队
时间限制: 1 Sec 内存限制: 32 MB

题目描述

N只小白鼠(1 <= N <= 100),每只鼠头上戴着一顶有颜色的帽子。现在称出每只白鼠的重量,要求按照白鼠重量从大到小的顺序输出它们头上帽子的颜色。帽子的颜色用“red”,“blue”等字符串来表示。不同的小白鼠可以戴相同颜色的帽子。白鼠的重量用整数表示。

输入

多案例输入,每个案例的输入第一行为一个整数N,表示小白鼠的数目。
下面有N行,每行是一只白鼠的信息。第一个为不大于100的正整数,表示白鼠的重量,;第二个为字符串,表示白鼠的帽子颜色,字符串长度不超过10个字符。
注意:白鼠的重量各不相同。

输出

每个案例按照白鼠的重量从大到小的顺序输出白鼠的帽子颜色。

样例输入
1
79 omi
9
46 lcg
92 cru
37 ceq
54 vhr
17 wus
27 tnv
13 kyr
95 wld
34 qox
样例输出
omi
wld
cru
vhr
lcg
ceq
qox
tnv
wus
kyr

解题思路
运用选择排序,在进行位置交换时,同时交换 体重(整型) 和 颜色(字符数组) 两个变量即可。

Submission

#include<stdio.h>
#include<string.h>
int main(){
    int i, j = 0, n;
    int x;
    while( scanf("%d", &n) != EOF ){
        char col[101][11] = {0};
        int weight[101] = {0};
        for( i = 0; i < n; i++ ){
            scanf("%d %s", &weight[i], col[i]);
        }   
        for( i = 0; i < n; i++ ){
            int k = i;
            for( j = i; j < n; j++ ){
                if( weight[j] < weight[k] ){
                    k = j;
                }
            }
            if( k != i ){
                int temp = weight[k];
                weight[k] = weight[i];
                weight[i] = temp;
                char temp_str[1][11] = {0};
                strcpy( temp_str[0], col[i] );
                strcpy( col[i], col[k] );
                strcpy( col[k], temp_str[0]);
            }
        }
        for( i = n-1; i >= 0; i-- ){
            printf("%s\n", col[i]);
        }
    }
    return 0;
}    

问题 G: 中位数
时间限制: 1 Sec 内存限制: 32 MB

题目描述
中位数定义:一组数据按从小到大的顺序依次排列,处在中间位置的一个数(或最中间两个数据的平均数).
给出一组无序整数,求出中位数,如果求最中间两个数的平均数,向下取整即可(不需要使用浮点数)

输入
该程序包含多组测试数据,每一组测试数据的第一行为N,代表该组测试数据包含的数据个数,1<=N<=10000.
接着N行为N个数据的输入,N=0时结束输入

输出
输出中位数,每一组测试数据输出一行

样例输入
1
468
15
501
170
725
479
359
963
465
706
146
282
828
962
492
996
943
0
样例输出
468
501
提示

按题目要求模拟即可

解题思路
在math函数中,floor(double x)函数用于向下取整,ceil(double x)函数用于向上取整,round(double x)用于四舍五入。
先排序,后计算中位数。

Submission

#include<stdio.h>
#include<math.h>
int main(){
    int i, j = 0, n;
    int x;
    while( scanf("%d", &n) && n != 0 ){
        double num[10001] = {0};
        for( i = 0; i < n; i++ ){
            scanf("%lf", &num[i]);
        }   
        //选择排序
        for( i = 0; i < n; i++ ){
            int k = i;
            for( j = i; j < n; j++ ){
                if( num[j] < num[k] ){
                    k = j;
                }
            }
            if( k != i ){
                double temp = num[k];
                num[k] = num[i];
                num[i] = temp;
            }
        }
        //计算中位数
        if( n % 2 != 0 ){
            printf("%.0f\n",  num[n/2]);
        }
        else{
            printf("%.0f\n", floor((num[n/2]+num[n/2-1])/2));
        }
    }
    return 0;
}    

问题 H: 整数奇偶排序
时间限制: 1 Sec 内存限制: 32 MB

题目描述

输入10个整数,彼此以空格分隔。重新排序以后输出(也按空格分隔),要求:
1.先输出其中的奇数,并按从大到小排列;
2.然后输出其中的偶数,并按从小到大排列。

输入

任意排序的10个整数(0~100),彼此以空格分隔。

输出

可能有多组测试数据,对于每组数据,按照要求排序后输出,由空格分隔。

样例输入
0 56 19 81 59 48 35 90 83 75
17 86 71 51 30 1 9 36 14 16
样例输出
83 81 75 59 35 19 0 48 56 90
71 51 17 9 1 14 16 30 36 86
提示

多组数据,注意输出格式

  1. 测试数据可能有很多组,请使用while(cin>>a[0]>>a[1]>>…>>a[9])类似的做法来实现;

  2. 输入数据随机,有可能相等。

解题思路
可以先分奇偶再排序,也可以先排序再分奇偶输出。

Submission

#include<stdio.h>
#include<math.h>
int main(){
    int i, j = 0, n;
    int x;
    int num[11] = {0};
    while( scanf("%d", &num[0]) != EOF ){
        for( i = 1; i < 10; i++ ){
            scanf("%d", &num[i]);
        }
        //插入排序
        j = 0;
        for( i = 1; i < 10; i++){
            int temp = num[i];
            int j = i;
            while(j > 0 && temp < num[j-1]){
                num[j] = num[j-1];
                j--;
            }
            num[j] = temp;     
        }
        //分奇偶输出
        for( i = 9; i >= 0; i--){
            if( num[i] % 2 != 0 ){
                printf("%d ", num[i]);
            }
        }
        for( i = 0; i < 10; i++){
            if( num[i] % 2 == 0 ){
                printf("%d ", num[i]);
            }
        }
        printf("\n");
    }
    return 0;
}    

问题 I: 排名
时间限制: 1 Sec 内存限制: 32 MB

题目描述
今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑每题的分值,所以并不是最后的排名。给定录取分数线,请你写程序找出最后通过分数线的考生,并将他们的成绩按降序打印。

输入
测试输入包含若干场考试的信息。每场考试信息的第1行给出考生人数N ( 0 < N < 1000 )、考题数M ( 0 < M < = 10 )、分数线(正整数)G;第2行排序给出第1题至第M题的正整数分值;以下N行,每行给出一名考生的准考证号(长度不超过20的字符串)、该生解决的题目总数m、以及这m道题的题号(题目号由1到M)。
当读入的考生人数为0时,输入结束,该场考试不予处理。

输出
对每场考试,首先在第1行输出不低于分数线的考生人数n,随后n行按分数从高到低输出上线考生的考号与分数,其间用1空格分隔。若有多名考生分数相同,则按他们考号的升序输出。

样例输入
3 5 32
17 10 12 9 15
CS22003 5 1 2 3 4 5
CS22004 3 5 1 3
CS22002 2 1 5
0
样例输出
3
CS22003 63
CS22004 44
CS22002 32

解题思路
这题比较简单,计算好每个人的分数后按题目要求排序即可。

Submission

#include<stdio.h>
#include<string.h>
int main(){
    int i = 0, j = 0, n;
    while( scanf("%d", &n) != EOF && n != 0 ){
        int m = 0;
        int g = 0;
        int numofStu = 0;
        int score[11];
        char id[1000][21] = {0};
        int numofClass[1000][11]={0}; 
        int scoreofStu[1000]={0};
        scanf("%d", &m);
        scanf("%d", &g);
        for( i = 0; i < m; i++ ){
            scanf("%d", &score[i]);
        }
        for( i = 0; i < n; i++){
            scanf("%s", id[i]);
            scanf("%d", &numofClass[i][0]);
            for( j = 1; j <= numofClass[i][0]; j++){
                scanf("%d", &numofClass[i][j]);
                scoreofStu[i] = scoreofStu[i] + score[numofClass[i][j]-1];//计算每个同学的分数
            }
            if( scoreofStu[i] >= g ){
                numofStu ++;
            } //计算合格人数
        }
        for( i = 0; i < n; i++ ){//根据每个同学的分数进行选择排序
            int k = i;
            for( j = i; j < n; j++ ){
                if( scoreofStu[j] < scoreofStu[k] ){
                    k = j;
                }
            }
            if( k != i ){
                int temp = scoreofStu[k];
                scoreofStu[k] = scoreofStu[i];
                scoreofStu[i] = temp;
                char temp_str[1][21] = {0};
                strcpy( temp_str[0], id[i] );
                strcpy( id[i], id[k] );
                strcpy( id[k], temp_str[0]);
            }
        }
        printf("%d\n", numofStu);//输出
        for( i = numofStu-1 ; i >= 0; i-- ){
            if( scoreofStu[i] >= g)
            printf("%s %d\n", id[i], scoreofStu[i]);            
        }
        printf("\n");
    }
    return 0;
}    

好啦,貌似这本算法书里面的排序没有放在一起讲,先讲的冒泡、选择和插入,快速排序得到后面的章节才讲,继续刷~

猜你喜欢

转载自blog.csdn.net/Marilynmontu/article/details/82025014