C中最大+第二大数

Largest + second largest number in C

请帮帮我。 我的代码有什么问题?我的代码在第三个示例案例和其他一些数字中不起作用?

问题:

格式输入 输入以整数 T 开头,描述测试用例的数量。每个测试用例都以一个整数 N 开头,即 Lili 拥有的盒子数量。下一行将包含 N 个数字 Vi,每个数字描述第 i 个盒子中硬币的价值。保证值永远在-1000000到1000000之间

格式化输出 对于每个测试用例,输出由“Case #X: Y”组成的一行,其中 X 是测试用例编号,Y 是 Lili 通过恰好选择 2 个框可以得到的最大值。

约束条件

•1≤T≤10

• 2 ≤ N ≤ 1, 000, 000

• −1, 000, 000 ≤ Vi ≤ 1, 000, 000

示例输入(标准输入)

3

5

1 2 3 4 5

4

4 4 4 4

3

10 1 2

示例输出(标准输出)

案例#1:9

案例 #2:8

案例 #3:12

*所以,这道题想求和第一和第二最大数

*不知道为什么我的代码在第三个示例案例中不起作用,一些数字总和为 20,请帮助

这是我到目前为止所写的内容

#include<stdio.h>
int main(){
int t;
long int n, max1, max2, v[100];

scanf("%d", &t);

for(int i=1; i<=t; i++){
  if(t>=1 && t<=10){

  scanf("%ld", &n);}

    if(n>=2 && n<=1000000){
        for(long int j=0; j<n; j++){
        scanf("%ld", &v[j]);
        }

        max1 = v[0];
          for(long int j=0; j<n; j++){
            if(max1<v[j]){
              max1=v[j];
            }
          }
        max2 = v[0];
          for(long int j=0; j<n; j++){
            if(v[j]!=max1 && v[j]>max2){
              max2=v[j];
            }
          }

            long int sum=max1+max2;
            printf("Case #%d: ", i);
            printf("%ld\n", sum);
    }

}
return 0;
}

问题出在语句 max2 = v[0]; 对于示例案例:10 1 2,max2=10。 因此,没有其他值 (1 2) 大于 10。因此,在第三个示例测试用例中永远不会满足 if 条件 if(v[j]!=max1 && v[j]>max2)max2=10

解决方案:为 max2 分配一些负数(最初)。我建议你使用 INT_MIN

PS:此更改不适用于第二个示例测试用例。

您用于查找 max2 的代码由于多种原因是错误的。你这样做:

if(v[j]!=max1 && v[j]>max2){

考虑像“1 5 5”这样的数据会发生什么。首先,您会发现 max1 为 5。然后由于 v[j]!=max1,您从未将 max2 设置为 5,因此它将保持值 1。

尝试单循环:

// max1 shall be the largest of the first two numbers
// max2 shall be the smallest of the first two numbers
if (v[0] > v[1])
{
    max1 = v[0];
    max2 = v[1];
}
else
{
    max1 = v[1];
    max2 = v[0];
}

// Start the loop from the third element
for(long int j=2; j<n; j++)
{
    if (v[j] > max1)
    {
        // New maximum
        max2 = max1;
        max1 = v[j];
    }
    else if (v[j] > max2)
    {
        // New second highest number
        max2 = v[j];
    }
}

问题就在这里

max2 = v[0];
for(long int j=0; j<n; j++){
  if(v[j]!=max1 && v[j]>max2){
    max2=v[j];
  }
}

当数字为 10、1、2 时,您从 max1 = 10max2 = 10 开始。然后拒绝所有不是 max1 且小于或等于 max2 的东西。即 10(等于 max1)、1(小于 10)和 2(也小于 10)。所以你数 10 两次。当最大的数字是第一个时,你总是会遇到这个问题。

一个简单的修复方法是将 max2 初始化为可能的最小长整数 LONG_MIN。因为总是至少有两个数字,所以这是安全的。

更好的算法是同时跟踪 max1 和 max2。而且由于我们是一次性完成的,因此无需存储输入。使用相同的技巧将它们初始化为最小的数字。

也没有必要使用long int;虽然按照标准,int 可以小到 16 位,除非您在某些高级环境中工作,否则它至少是 32 位。

#include<limits.h>
...

    for(int i=1; i<=t; i++){
        int n;
        scanf("%d", &n);

        // Initialize our maxes to the smallest possible integer.
        // Everything will be equal or larger.
        int max[2] = {INT_MIN};
        for(int j=0; j<n; j++){
            int input;
            scanf("%d", &input);

            // The input is larger than max[0]
            if( input > max[0] ) {
                // Make the largest the second largest.
                max[1] = max[0];
                // Make the input the new largest number.
                max[0] = input;
            // The input is smaller than max[0], but larger than max[1].
            } else if( input > max[1] ) {
                // Make the input the new second largest.
                max[1] = input;
            }
        }

        printf("Case #%d: ", i);
        printf("%d + %d = %d\n", max[0], max[1], max[0] + max[1]);
    }