結構體——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循環

各有利弊吧,學無止境啊

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