PTA習題解析:獲獎(Python)


獲獎

題干

在某次競賽中,判題規則是按解題數從多到少排序,在解題數相同的情況下,按總成績(保證各不相同)從高到低排序,取排名前 60% 的參賽隊(四舍五入取整)獲獎,請確定某個隊能否獲獎。

輸入格式

首先輸入一個正整數 T,表示測試數據的組數,然后是 T 組測試數據。每組測試的第一行輸入 1 個整數 n(1 ≤ n ≤ 15)和 1 個字符串 ms(長度小於 10 且不含空格),分別表示參賽隊伍總數和想確定是否能獲獎的某個隊名;接下來的 n 行輸入 n 個隊的解題信息,每行一個 1 個字符串 s(長度小於 10 且不含空格)和 2 個整數 m,g(0 ≤ m ≤ 10,0 ≤ g ≤ 100),分別表示一個隊的隊名、解題數、成績。當然,n 個隊名中肯定包含 ms。

輸出格式

對於每組測試,若某隊能獲獎,則輸出 “YES”,否則輸出 “NO”。引號不必輸出。

測試樣例

輸入

2
3 team001
team001 2 27
team002 2 28
team003 0 7
14 team010
team012 5 52
team013 5 55
team014 5 57
team005 7 77
team002 7 79
team001 7 89
team003 7 78
team014 7 70
team006 7 75
team009 7 84
team007 7 81
team010 5 62
team008 5 53
team011 5 59

輸出

YES
NO

解題思路

這道題分別把得分和答題數存在列表或者字典里,然后多次排序或遍歷后也能得出結果,但是這種解法並不是很簡潔。注意輸入的數據是隊伍名、隊伍答題數和隊伍得分,這些屬性的相關性是很高的,可以構造一個 Team 類來描述。

class Team(object):
    def __init__(self, name, count, grade):
        self.name = name      #隊名
        self.count = count    #答題數
        self.grade = grade    #得分

構造 Team 類以后,對於每一組輸入數據可以實例化為一個 Team 對象來存儲。為了方便調試,可以重寫魔術方法 “def __ str __(self)”,這樣在輸出 Team 對象時就可以按照我們規定的格式來構造字符串。

def __str__(self):
    return ("name: {}; count: {}; grade: {}".format(self.name, self.count, self.grade))

例如對於測試樣例 1,使用 print() 輸出 Team 對象的效果如下。

根據題目要求“取排名前 60% 的參賽隊(四舍五入取整)獲獎”,也就是說需要按照某個規則(題意)對所有的隊伍進行排名。按照這個思路,我們可以重載 Team 類的 “<” 運算符,這樣對一個 Team 對象的 list 使用 sorted() 函數排序時,就可以按照我們制定的規則來排序。為了實現這一點,需要重寫魔術方法 “def __ lt __(self, other)”。

def __lt__(self, other):
    if self.count == other.count:    #答題數相同的情況下比較總分
        return self.grade > other.grade
    else:                            #答題數不同的情況下比較答題數
        return self.count > other.count

為 Team 對象指定了排序的規則后,接下來就很明了了。首先先讀取測試點的數據,將每一組數據實例化為一個 Team 對象后,添加入一個 list 中。

testNum = int(input())    #隊伍總數
for i in range(testNum):
    teamNum, teamName = input().split(" ")
    teamNum = int(teamNum)

    teams = []    #存放所有 Team 對象的 list
    for j in range(teamNum):
        name, count, grade = input().split(" ")
        aTeam = Team(name, int(count), int(grade))    #實例化 Team 對象
        teams.append(aTeam)

接下來只需要對這個 list 排序,即可將所有隊伍按照獲獎順序排列。

'''
print("排序前:")
for team in teams:
    print(team)
'''        
teams = sorted(teams)
'''
print("排序后:")
for team in teams:
    print(team)
'''

此處以測試樣例 2 為例,將排名前后的情況輸出查看。

最后只需要遍歷列表,如果要求判斷的隊伍的下標在 list 的前 60%,說明有獲獎,輸出即可。注意下標是從 0 開始計算的,而且需要使用 round() 函數四舍五入。

for j in range(len(teams)):
    if teams[j].name == teamName:
        if j + 1 <= round(len(teams) * 0.6):
            print('YES')
        else:
            print('NO')
        break

完整代碼

class Team(object):
    def __init__(self, name, count, grade):
        self.name = name
        self.count = count
        self.grade = grade
    
    def __str__(self):
        return ("name: {}; count: {}; grade: {}".format(self.name, self.count, self.grade))
    
    def __lt__(self, other):
        if self.count == other.count:
            return self.grade > other.grade
        else:
            return self.count > other.count

testNum = int(input())
for i in range(testNum):
    teamNum, teamName = input().split(" ")
    teamNum = int(teamNum)

    teams = []
    for j in range(teamNum):
        name, count, grade = input().split(" ")
        aTeam = Team(name, int(count), int(grade))
        teams.append(aTeam)

    teams = sorted(teams)
    for j in range(len(teams)):
        if teams[j].name == teamName:
            if j + 1 <= round(len(teams) * 0.6):
                print('YES')
            else:
                print('NO')
            break

參考資料

Python 面向對象編程
Python的富比較方法__lt__、__gt__之間的關聯關系分析
python 列表排序方法sort、sorted技巧篇


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM