HDOJ 2093 考試排名(表格,字串)
阿新 • • 發佈:2019-02-15
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;
}