C-KY214 最大的两个数

今年五一因为疫情的原因,回不去。只好刷下题目。
以下是牛客网考研机试中的一个题目。
在这里插入图片描述题目要求找出每列中最大的两个数,然后输出的时候要求保留原矩阵的排列顺序。换句话说,输出的时候要根据矩阵的顺序进行,而不是固定将最大和次大的依此输出。否则是通不过的。

二维数组实现方法

使用二维数组来实现最容易和直接想到的,程序运行速度较快但是占用的内存会多一些。
简单说下思路:

  1. 定义1个20个元素的数组d
  2. 定义2个二维数组e和f,其中e中存储最大值,而f中储存次大值。其中e的第2个维度存储其对应的行数。
  3. 依此读取输入的每个值,如果其值大于最大值,则将次大值中的更新为最大值的值。之后再将最大值进行更新。

代码实现

下面是对应的代码:

#include <stdio.h>

int main(int argc, char *argv[]) {
    int c;
    while (scanf("%d", &c) != EOF) {
        int d[20] = {0};
        int e[5][2] = {0};
        int f[5][2] = {0};
        d[0] = c;
        for (int i = 1; i < 20; ++i) {
            scanf("%d", &c);
            d[i] = c;
        }
        int num = 0;
        //每1列
        for (int j = 0; j < 5; ++j) {
            for (int i = 0; i < 4; ++i) {
                c = d[j + i * 5];
                if (c > e[num][0]) {
                    //次大值更新
                    f[num][0] = e[num][0];
                    //最大值更新
                    e[num][0] = c;
                    //更新最大值的行数
                    e[num][1] = i;
                } else if (c > f[num][0] && f[num][0] < e[num][0]) {
                    //更新次大值
                    f[num][0] = c;
                    //更新次大值的行数
                    f[num][1] = i;
                }
            }
            num++;
        }
        //输出每行顺序最小的行
        for (int k = 0; k < 4; ++k) {
            if (e[k][1] < f[k][1]) {
                printf("%d ", e[k][0]);
            } else {
                printf("%d ", f[k][0]);
            }
        }
        if (e[4][1] < f[4][1]){
            printf("%d\n", e[4][0]);
        }else{
            printf("%d\n", f[4][0]);
        }
        //输出每行顺序最小的行
        for (int k = 0; k < 4; ++k) {
            if (e[k][1] > f[k][1]) {
                printf("%d ", e[k][0]);
            } else {
                printf("%d ", f[k][0]);
            }
        }
        if (e[4][1] > f[4][1]){
            printf("%d\n", e[4][0]);
        }else{
            printf("%d\n", f[4][0]);
        }
    }
    return 0;
}

最后是通过后的结果:
在这里插入图片描述由于代码写得比较繁琐,因此占用的内存比较多。
下面再分享一种更为逻辑更为简单的方法。

一维数组实现方法

首先我们定义1个只有10个元素的数组e,用于存储相应输出的结果。而定义1个20个元素的数组d来存储输入的每个结果。
想法就是让每组前2个元素存储的是最大和次大的值。当输入1个值时,我们将其与每组的最大和次大值进行比较。因为假定此时的大小顺序已经确定。
此时会出现4种情况,我们使用表格的形式进行说明,使用a表示每组第1个值,而b表示每组第2个值,而c表示输入的值:

ab说明
c > ac > bc为最大值
c > ac < bc为次大值
c < ac > bc为次大值
c < ac < b舍弃,c不是最大值和最小值
情况1

对于情况1,可以看到当c > ac > b时,说明此时c为最大值。那么此时该组的次大值是哪个呢?此时不妨让ab再比较一次。如果a > b,那么说明a是次大值,此时直接让c替换b上的值即可。因为此时c的顺序是在ab之后的。
但是,如果b > a,说明此时b是次大值。那么我们就需要将次大值b往前移动1位替换掉a,再将c替换b原来的值。

情况2

对于情况2,此时c > ac < b,说明c此时是次大值,而b是最大值。此时b的顺序在后面,按照大小顺序,需要进行相应的移位操作。只要将b往前移动1位替换掉原有的次大值a,再将c的值写入即可。

情况3

对于情况3,此时c < ac > b,说明c此时仍然是次大值,但是当前情况a是最大值。由于a的顺序在前面,此时就不需要进行任何的移位操作,直接将c的值覆盖原有次大值b的值即可。

情况4

对于情况4,此时cab都小,这说明c不是最大值和次大值,直接将其舍弃即可。

代码实现

说完以上的思路,下面是对应实现的代码:

#include <stdio.h>

int main(int argc, char *argv[]) {
    int c;
    while (scanf("%d", &c) != EOF) {
        int d[20] = {0};
        int e[10] = {0};
        int prev, next;
        d[0] = c;
        for (int i = 1; i < 20; ++i) {
            scanf("%d", &c);
            d[i] = c;
        }
        for (int j = 0; j < 5; ++j) {
            prev = j * 2;
            next = j * 2 + 1;
            for (int i = 0; i < 4; ++i) {
                c = d[j + i * 5];
                if (c >= e[prev] && c >= e[next]) {
                    //c为最大值
                    if (e[prev] >= e[next]) {
                        //e[prev]为次大值
                        e[next] = c;
                    } else {
                        //e[next]为次大值
                        e[prev] = e[next];
                        e[next] = c;
                    }
                } else if (c >= e[prev] && c <= e[next]) {
                    //c为次大值
                    e[prev] = e[next];
                    e[next] = c;
                } else if (c <= e[prev] && c >= e[next]) {
                    //c为次大值
                    e[next] = c;
                }
            }
        }
        for (int k = 0; k < 2; ++k) {
            for (int i = 0; i < 4; ++i) {
                printf("%d ", e[i * 2 + k]);
            }
            printf("%d\n", e[4 * 2 + k]);
        }
    }
    return 0;
}

最后就是输出的问题,此时先按奇数顺序输出,再按偶数顺序输出即可得到最终的答案。因为我们默认假定每组第1个元素是最大值,而每组第2个元素是次大值。而在这个过程中,值会根据实际的情况发生变动,但是其顺序已经在运行的过程中被固定了。
下面是通过后的结果:
在这里插入图片描述可以看到运行的时间比之前使用二维数组的时间还要长一些。但是占用的内存大小却小了很多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值