AcWing1561 PAT 評測 詳細題解

2021-10-10 18:09:35 字數 3964 閱讀 5901

pat 的排名列表是根據狀態列表產生的,狀態列表中顯示了所有提交記錄的分數。

現在,請你為 pat 生成排名列表。

輸入格式

第一行包含三個整數 n,k,m,分別表示總使用者數量,題目數量,以及提交數量。

使用者編號是從 00001 到 n 的 5 位數字。

問題編號從 1 到 k。

第二行包含 k 個整數 p1,p2,…,pk,其中 pi 表示第 i 題的滿分。

接下來 m 行,每行包含乙個提交資訊,包括使用者編號,題目編號,以及得分。

當提交無法正確編譯時,得分顯示 −1,否則是乙個 [0,該題滿分] 範圍內的整數。

注意,無法編譯的情況雖然顯示 −1,但得分上算作 0 分。

輸出格式

以下列格式輸出排名列表:

其中,rank 是根據 total_score 計算的,所以擁有相同 total_score 的使用者的 rank 也相同。

s[i] 是第 i 個問題獲得的分數。

如果某個問題,使用者從未提交過**,則用 - 來表示這道題的分數。

如果某個問題,使用者多次提交過**,則取最高分為這道題的分數。

列表必須根據排名從前到後輸出,對於排名相同的使用者,根據滿分題目的數量以降序對使用者排序,如果仍有排名相同的情況,則按 id 公升序的順序排序。

對於從未提交過任何**,或者從未提交過任何編譯通過的**的使用者,輸出時不予考慮。

資料範圍

1≤n≤104,

1≤k≤5,

1≤m≤105

每道題的滿分為不超過 30。

輸入樣例:

7 4 20

20 25 25 30

00002 2 12

00007 4 17

00005 1 19

00007 2 25

00005 1 20

00002 2 2

00005 1 15

00001 1 18

00004 3 25

00002 2 25

00005 3 22

00006 4 -1

00001 2 18

00002 1 20

00004 1 15

00002 4 18

00001 3 4

00001 4 2

00005 2 -1

00004 2 0

輸出樣例:

1 00002 63 20 25 - 18

2 00005 42 20 0 22 -

2 00007 42 - 25 - 17

2 00001 42 18 18 4 2

5 00004 40 15 0 25 -

根據需要輸出的變數來新增結構體內的元素

rank user_id total_score s[1] … s[k]

而觀察其中的 「s[1] … s[k]」 發現又有乙個變數k,因此可以考慮將其分開輸出。

const

int n=

10010

;//人數最多10000

struct stu

;//每道題得分

int sum;

//總分

int final_rank;

//最終排名

}stus[n]

;//結構體陣列變數

主函式:

int

main()

while

(m--

)for

(int p=

0;p<

6;p++

)//這裡為什麼不能直接: stus[num].qs[i]=max(stus[num].qs[i],s);

//因為如果每次得分都是-1,那麼最終stus[num].qs[i]=-1;正確的應該是0

//但是不可認為 stus[num].qs[i]經過次程式片段後只能大於等於0

//因為有可能此人根本就沒做過這道題,此時仍為-1if(

max(stus[num]

.qs[i]

,s)>=0)

else

}

for

(int num=

1;num<=n;

++num)}}

}

//注意sort函式的起始範圍(從1開始)

sort

(stus+

1,stus+

1+n,cmp)

;//cmp函式提供總分排名的三個條件

for(

int g=

0;g<=n-1;

++g)

else

}

for

(int b=

1;b<=n;

++b)

}else}}

cout<}}

副函式部分:

int

getid

(char str)

if(num)

}return ret;

}int

max(

int a,

int b)

else

}bool cmp

(struct stu a,

struct stu b)

else

if(a.cnt != b.cnt)

else

}

最後完整**如下:

#include

using namespace std;

#include

int n,k,m;

//n表示使用者數量 k表示題目數量 m表示提交數量

char id[6]

;const

int n=

10010

;struct stu

;int sum;

int final_rank;

// bool operator<(const stu &x) constelse if(cnt!=x.cnt)else

// }

}stus[n]

;int

getid

(char str)

;int

max(

int a,

int b)

; bool cmp

(struct stu a,

struct stu b)

;int

main()

while

(m--

)for

(int p=

0;p<

6;p++)if

(max

(stus[num]

.qs[i]

,s)>=0)

else

}for

(int num=

1;num<=n;

++num)}}

}sort

(stus+

1,stus+

1+n,cmp)

;for

(int g=

0;g<=n-1;

++g)

else

}for

(int b=

1;b<=n;

++b)

}else}}

cout<}int

getid

(char str)

if(num)

}return ret;

}int

max(

int a,

int b)

else

}bool cmp

(struct stu a,

struct stu b)

else

if(a.cnt != b.cnt)

else

}

hdu 1561 依賴揹包

題意 n座城堡,每個裡面都有寶物,要求在你可以攻占m個城堡得到的最多的寶物,但是如果要攻破乙個城堡,必須要攻破它依賴的那個城堡,例如,如果a依賴b,那麼如果想要攻破a就必須先攻破b。把每個城堡看作是物品,那麼這個物品的城堡數量是1,價值就是寶物了。解題思路 根據題意知道這種關係會形成一顆多叉樹,根節...

hdu1561 樹形揹包初探

problem description acboy很喜歡玩一種戰略遊戲,在乙個地圖上,有n座城堡,每座城堡都有一定的寶物,在每次遊戲中acboy允許攻克m個城堡並獲得裡面的寶物。但由於地理位置原因,有些城堡不能直接攻克,要攻克這些城堡必須先攻克其他某乙個特定的城堡。你能幫acboy算出要獲得盡量多的...

HDU 1561 樹形dp 揹包

分析 攻下一座城堡的前提是要先攻下它的前驅城堡,建立乙個以0為根結點的樹,他的權值為0 dp i,j 表示以i為根結點去j個的最大值。dp i,1 v i v i 為攻下i城堡獲得的寶藏 對與u結點取j 1個,可以轉化為以孩子i為根取k個 以自己為根取j 1 k個和自己取j 1個的最大值 為什麼是j...