PTA 求最大、次大和第3大的值 (25 分)

本题目要求读入n个整数,要求用最少的比较次数,输出它们的最大值、第2大的值和第3大的值。例如,对于13 13 1 10 34 10这6个数,最大值为34,第2大的值为13,第3大的值为10。
输入格式:
输入有两行。第一行为整数个数n(≤1 000 000),第二行给出n个以空格分隔的整数。
输出格式:
对每一组输入,在一行中输出最大值、第2大的值和第3大的值值,中间以一个空格分隔,但行尾没有多余空格。
如果输入数据不足三个,则输出“Invalid Input”。
如果没有第3大的值,则输出“There is no third largest element”。
如果没有第2大和第3大的值,则输出“There is no second largest and third largest element”。
输入样例:
6
13 13 1 10 34 10
输出样例:
34 13 10

一点分析:
这道题的数据量,可见庞大。一般的排序方法并不凑效(类似于冒泡算法的这种),所以这里的排序,用的是一种最“手把手”的方法。就是把输入的数字不断地与最大的数字进行比较,有点类似于线性表的插入操作。废话不多说,直接上代码。

#include<stdio.h>
#define Max 10000000 //先来个宏定义,为什么数值是10000000,下面就解释 
int main()
{
 long long int n;                  //因为题目说了要将n个整数进行比较,但是并没有说是正整数
 long long int t,i;     //但是为什么要初始化为一个很小的负数呢? 
 long long int med=-Max,min=-Max; //想象一个场景,如果是直接int max的话,max默认为0 
 long long int max=-Max;          //现在输入的数全部是负数,判断负数比0小,那么这个程序就失去正确性了
 //虽然这题是AC了,但是后来仔细一想,其实还是有漏洞的,如果输入的数字比-10000000还小呢 
 scanf("%lld",&n);
 if(n<3)
 {
  printf("Invalid Input");  
  return 0;
 }
 for(i=0;i<=n-1;i++)  //现在开始输入数字 
 {
  scanf("%lld",&t);//每次输入一个数字 
  if(t>max&&t!=max&&t!=min&&t!=med)//首先先与最大的数字进行比较 
  {
   min=med;        //这整个过程我称它为插入操作  
   med=max;    //相当于t->max->med->min 
   max=t;  //赋值的顺序一定不能乱 
   continue; 
  } 
  if(t>med&&t!=max&&t!=min&&t!=med) //一系列数中,可能会有相同数字 
  {
   min=med;   //赋值的顺序同样不能乱 
   med=t;
   continue;
  }
  if(t>min&&t!=max&&t!=min&&t!=med)
  {
   min=t;
   continue;
  }
 }
 if(min==med&&min==-Max)                  //这种情况会出现在所有数都一样的情况下 
 {
  printf("There is no second largest and third largest element");
  return 0;
 }
 if(min==-Max)  //一般情况,没有第三大的数字 
 {
  printf("There is no third largest element");
  return 0;
 }
 if(med==-Max)//一般情况,没有第二和第三大的数字 
 {
  printf("There is no second largest and third largest element");
  return 0;
 }
 printf("%lld %lld %lld",max,med,min);
 return 0;
}
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值