1. 程式人生 > >題解報告:hdu 2093 考試排名

題解報告:hdu 2093 考試排名

初始 c++ 讀取 實時 相互 計算 入參 spa 排序規則

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2093

Problem Description C++編程考試使用的實時提交系統,具有即時獲得成績排名的特點。它的功能是怎麽實現的呢? 我們做好了題目的解答,提交之後,要麽“AC”,要麽錯誤,不管怎樣錯法,總是給你記上一筆,表明你曾經有過一次錯誤提交,因而當你一旦提交該題“AC”後,就要與你算一算帳了,總共該題錯誤提交了幾回。雖然你在題數上,大步地躍上了一個臺階,但是在耗時上要攤上你共花去的時間。特別是,曾經有過的錯誤提交,每次都要攤上一定的單位時間分。這樣一來,你在做出的題數上,可能領先別人很多,但是,在做出同樣題數的人群中,你可能會在耗時上處於排名的劣勢。 例如:某次考試一共8題(A,B,C,D,E,F,G,H),每個人做的題都在對應的題號下有個數量標記,負數表示該學生在該題上有過的錯誤提交次數,但到現在還沒有AC,正數表示AC所耗的時間,如果正數a跟上一對括號,裏面有個整數b,那就表示該學生提交該題AC了,耗去了時間a,同時,曾經錯誤提交了b次,因此對於下述輸入數據:
技術分享圖片

若每次錯誤提交的罰分為20分,則其排名從高到低應該是這樣的: Josephus 5 376 John 4 284 Alice 4 352 Smith 3 167 Bob 2 325 Bush 0 0 Input 輸入數據的第一行是考試題數n(1≤n≤12)以及單位罰分數m(10≤m≤20),每行數據描述一個學生的用戶名(不多於10個字符的字串)以及對所有n道題的答題現狀,其描述采用問題描述中的數量標記的格式,見上面的表格,提交次數總是小於100,AC所耗時間總是小於1000。 Output 將這些學生的考試現狀,輸出一個實時排名。實時排名顯然先按AC題數的多少排,多的在前,再按時間分的多少排,
的在,如果湊巧前兩者都相等,則按名字的字典序排,小的在前。每個學生占一行,輸出名字(10個字符寬),做出的題數(2個字符寬,對齊)和時間分(4個字符寬,對齊)。名字、題數和時間分相互之間有一個空格。 Sample Input 8 20 Smith -1 -16 8 0 0 120 39 0 John 116 -2 11 0 0 82 55(1) 0 Josephus 72(3) 126 10 -3 0 47 21(2) -2 Bush 0 -1 -8 0 0 0 0 0 Alice -2 67(2) 13 -1 0 133 79(1) -1 Bob 0 0 57(5) 0 0 168 -7 0 Sample Output Josephus 5 376 John 4 284 Alice 4 352 Smith 3 167 Bob 2 325 Bush 0 0 解題思路:題目要求講得很清楚,給出n個考試題目,單位罰時分為m,循環讀入參賽人員的信息,沒有限制參賽人數,但從AC時間小於1000,提交次數總是小於100來看,參賽人數即結構體數組長度開個(1W+1)就夠了。輸出規則是先按AC題目的數量從大到小排,再按AC總用時從小到大排,如果前兩者相等,則按名字的字典序輸出。另外用for循環讀入每道題的情況,然後進行字符串處理,當遇到第一個字符是‘-‘或者該字符串是"0",則continue繼續讀取,不進行下步操作。思路很清晰,題目很基礎!!! AC代碼:
 1
#include <bits/stdc++.h> 2 #define MAXN 10001 3 using namespace std; 4 struct node 5 { 6 char name[15];//用戶名 7 int ac;//ac的題目數量 8 int time;//總共花的時間 9 }stu[MAXN];//參加比賽的人數 10 bool cmp(node x,node y)//結構體排序規則 11 { 12 if(x.ac!=y.ac)return x.ac>y.ac;//先按ac的題量從大到小排 13 else if(x.time!=y.time)return x.time<y.time;//再按時間從小到大排 14 else return strcmp(x.name,y.name)<0;//最後是按字典序排名 15 } 16 int main() 17 { 18 int n,m,t=0;//n為考試題數,m為單位罰分數,t表示參賽人員的序號標記 19 char ch[10];//輸入每個題的得分情況 20 cin>>n>>m; 21 getchar(); //吃掉回車符 22 while(cin>>stu[t].name){//不斷輸入參賽人員的比賽信息 23 stu[t].ac=stu[t].time=0;//同時初始化為0,下面進行計算 24 for(int i=0;i<n;i++){ //循環讀個n個題目的比賽情況 25 cin>>ch; 26 if((ch[0]==-)||(strcmp(ch,"0")==0))continue;//等於負數或為0,說明沒有AC,直接進行下一個輸入 27 stu[t].ac++;//AC了就先計數,接下來算AC這道題所用的時間 28 int j,tmp=0; 29 for(j=0;j<(int)strlen(ch)&&ch[j]!=(;j++) 30 tmp=tmp*10+ch[j]-0;//先計算左括號旁邊的數字 31 stu[t].time+=tmp;//先加解題所用的時間 32 tmp=0; 33 if(j<(int)strlen(ch)){ 34 for(int k=j+1;k<(int)strlen(ch)-1;k++) //計算括號內的數 35 tmp=tmp*10+ch[k]-0; 36 } 37 stu[t].time+=tmp*m;//加上(之前錯誤提交次數乘上罰時總用時) 38 } 39 t++;//計數參賽人數 40 } 41 sort(stu,stu+t,cmp); //按規則排序 42 for(int i=0;i<t;i++) // 輸出排名信息 43 printf("%-10s %2d %4d\n",stu[i].name,stu[i].ac,stu[i].time);//按格式輸出 44 return 0; 45 }

題解報告:hdu 2093 考試排名