结构体——NO.1

问题 D: NO.1

时间限制: 1 Sec  内存限制: 128 MB
提交: 730  解决: 304
[提交][状态][讨论版][命题人:外部导入]

题目描述

    所谓NO.1,就是所有成绩都排在第一的同学,我们假设每个人只有理科,文科,体育这三门课。

我们现在假设某门成绩并列第一,并列的人都是这门功课第一名,并且保证数据不会出现2个NO.1

现给定n个人的信息,输出第一名的名字。

输入

多组数据,输入文件第一行为一个整数T,代表测试数据数。 (T<50)

接下来T个测试数据。  

每个测试数据的的第一行为一个整数n(n<=100),接下来有n行,每行的格式如下: 

名字 理科成绩 文科成绩 体育成绩 (数值越高代表成绩越好).

名字长度不超过20,3个成绩的为正整型.

输出

对于每个测试数据,输出NO.1的名字,如果不存在第一名,就输出"NO NO.1".

样例输入

3
2
lvhao 2 2 2
xiaoshua 1 1 1
2
lvhao 4 4 4
xiaoshua 4 4 3
3
lvhao 3 4 5
xiaoshua 1 3 1
pan 4 1 5

样例输出

lvhao
lvhao
NO NO.1

这道题想了很久,如果存在第一名很好找,只需要判断三门课都是第一就可,难点在如果不存在第一名的情况

曾想过一个思路:将每门课的第一名找出来,再看是否存在一个人同时是三门课的第一,但这样做的话考虑极端情况假设所有50个同学理科第一,50个同学文科第一,50个同学体育第一,要将文理科,体育第一的同学记下来就要开3个数组,还要查找在三个数组中同时出现的人,想想就有点烦

根据第三个样例,不存在第一名无非是后面的同学(4 1 5)某一科或者某两科比目前分数最好的同学(3 4 5)好,并且不会再有同学能够同时超过(4 1 5)和(3 4 5)这样的成绩,相当于无法超过(4 4 5),想到这点之后豁然开朗

下面贴出本小白代码

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
//定义学生结构体包含4个变量:名字,理科成绩,文科成绩,体育成绩
struct student
{
    string name;
    int science_score;
    int arts_score;
    int sports_score;
}s[101];
int main()
{
    //定义测试数据数
    int t;
    cin>>t;
    while(t--)
    {
        //接下来n行,表示n个学生
        int n;
        //定义每门课的最高分
        int science_max=0;
        int arts_max=0;
        int sports_max=0;
        //定义标记
        int mark=-1;
        cin>>n;
        for(int i=0;i<n;i++)
        {
            cin>>s[i].name>>s[i].science_score>>s[i].arts_score>>s[i].sports_score;
            //如果三门课同时超过当前最高分就更新最高分,标记同学,遍历下一个同学
            if(science_max<=s[i].science_score&&arts_max<=s[i].arts_score&&sports_max<=s[i].sports_score)
            {
                science_max=s[i].science_score;
                arts_max=s[i].arts_score;
                sports_max=s[i].sports_score;
                mark=i;
                continue;
            }
            //如果一门课超过当前最高分,说明当前最高分的同学不是NO.1,需要更新超过当前最高分的那门课的最高分
            if(science_max<s[i].science_score)
            {
                science_max=s[i].science_score;
                mark=-1;
            }
            if(arts_max<s[i].arts_score)
            {
                arts_max=s[i].arts_score;
                mark=-1;
            }
            if(sports_max<s[i].sports_score)
            {
                sports_max=s[i].sports_score;
                mark=-1;
            }
        }
        if(mark==-1)cout<<"NO NO.1"<<endl;
        else cout<<s[mark].name<<endl;
    }
}

多钻研还是很有成就感的


华丽丽的分割线

做完这道题后本人去网上搜索了一下别人的解法,以下几种解法更加简单方便理解

  1. 同我上面所说,先对每门课的成绩进行一个排序查找,但只需要记录每门课的最高分而不需要记录是哪个同学的分数,然后对所有同学进行遍历看是否存在一个同学的三门课分数都与三门课的最高分相同,此同学就是NO.1
  2. 先找出三门课都比当前最高分大的人,假定他是“NO.1”,接下来对所有同学进行遍历,如果存在某个同学的某门课比“NO.1”分数高,那么我们可以推断这个“NO.1”是冒牌货,不存在“N0.1”

总体来说,虽然上面两位的方法比本菜鸡短小精悍,但都用了两个for循环

各有利弊吧,学无止境啊

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章