1. 程式人生 > >HDOJ 2093 考試排名(表格,字串)

HDOJ 2093 考試排名(表格,字串)

HDOJ 2093
這是一道字串處理的題目。題目本身沒有太高深的演算法,只是以表格的形式處理很麻煩。比如出現的116(5),括號的讀入和處理。
看著解題報告完成的,收穫了很多。
第一,STL中的sort排序,自己定義了排序規則cmp函式,可以按照題目的要求進行排序。
第二,這裡用到了sscanf的讀取的一個技巧。認真分析這裡的sscanf的使用。
sscanf的用法:
a.本題:
sscanf(s,”%d(%d)”,&x,&y); //從字串中讀取出x,y.

b.將字元讀入到字串中
sscanf(“12345”,”%s”,str);
printf(“用法三\nstr = %s\n”,str);
則 str=12345
第三,用結構體解決類似問題,很明顯的面向物件的思想。
第四,不要害怕一道題,這題目上次遇見時看都不想看,實際上靜下心來看不是很困難。

對了還有一個地方要說明一下,就是解決帶有括號的那個地方。下面有一行程式碼是:

    if(s[1]=='('||strlen(s)>=5)

剛開始沒看懂原作者的意圖,後來覺得大概是他假設如果此題在AC但是有錯誤提交的情況下,如果提交的時間在1-9之間,那麼s[1]就儲存的應該是‘(’,如果提交的時間10-1000的話,那麼比如20(3),字串的長度至少大於等於5.所以strlen(s)>=5.

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <string> #include <algorithm> #include <iostream> #include <ctype.h> #include <set> #include <map> #include <vector> using namespace std; struct Stu { int acnum,time; char name[10]; }; int n,m,i,num,wa,ac,x,y; Stu data[100000]; char s[20]; bool pd; bool
cmp(Stu x,Stu y){ if(x.acnum >y.acnum) return true; if(x.acnum ==y.acnum &&x.time <y.time ) return true; if(x.acnum ==y.acnum &&x.time ==y.time &&strcmp(x.name ,y.name)<=0 ) return true; return false; } int main(){ cin>>n>>m; //考試題目數和罰時分 num=1; while(scanf("%s",data[num].name )!=EOF){ data[num].acnum=0;data[num].time=0;wa=0;ac=0; //初始化 for(i=1;i<=n;i++){ memset(s,'\0',sizeof(s)); pd=false; scanf("%s",s); if(s[0]=='-'||s[0]=='0'){ //沒有AC pd=true; } if(s[1]=='('||strlen(s)>=5){ //AC了,但是有錯誤提交 pd=true; ++ac; sscanf(s,"%d(%d)",&x,&y); //從字串中讀取出x,y.sscanf的一個重要用法 data[num].time+=x; wa+=y; } if(pd==false){ //AC且沒有錯誤提交 ++ac; sscanf(s,"%d",&x); data[num].time +=x; } } data[num].time +=wa*m;//加上罰時 if(data[num].time<0) { data[num].time =0; } data[num].acnum =ac; ++num; //記錄下一個選手 } sort(data+1,data+num,cmp); //自定義sort的排序規則 for(i=1;i<=num-1;i++){ printf("%-10s %2d %4d\n",data[i].name ,data[i].acnum ,data[i].time );//輸出名字(10個字元寬),做出的題數(2個字元寬,右對齊)和時間分(4個字元寬,右對齊)。名字、題數和時間分相互之間有一個空格。 } return 0; }