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...