题意:有n组数据,每组数组先是给出一个tournament name,然后是t个球队的名字,然后g个比赛的结果,然后要输出每组数据的积分榜(standings),积分榜有多个域,这里points、games played、goal difference 是可以根据其他计算出来的。所以,对每支球队只需保存球队名、wins、ties、losses、goals scored、goals against即可,定义一个结构体team。这里理解题意主要是区别points和goals就可以了。
思路:主要就是读入数据,对每个比赛结果处理相应的结构体就行了。结束之后对结构体数组按题给的要求排序,输出即可。结构体排序题。(另一种想法,如果每个球队都是有比赛结果的,那么在开始的球队名称输入时,就可以忽略,然后直接处理比赛结构,每次都在tlist里找,找到了就处理,没找到就新建一个加入到数组,这样查找的量还小一点~没试过,不知道能不能AC)
注意:1.这里tournament name 和 team name 都是可以有空格的,所以不能用scanf,防溢出一般都用fgets。关键是fgets与scanf搭配用时,要特别注意前面的scanf是把换行符放回输入流的。(这个直接写的时候可能注意到,但这里是由scanf改为fgets的就容易忘!下次把scanf改成其他输入函数时,要记得看前后其他输入函数的搭配啊。)
2.这里排序的规则,注意其中是less games,以及大小写不敏感。(这里因为开始写的是升序排列,后来改成降序的时候,就忽略了是less games。所以说,修改的时候要注意题目相关要求。大小写那个倒是注意了,但是转小写的地方不知道自己怎么写成了错的代码,一直没发现~这里忽略大小写进行比较,有人用了linux下的strcasecmp或win 下的stricmp,它们是包含在strings.h头文件里的,不是C/C++的标准头文件)
3.拼写错误。这题有多个拼写错误虐了我!首先用读文件的方式测试时,文件名是.in,被我写成了.int,结果输出的n还恰好就是文件里的n=2,而tournament name输出是乱码,这个错太难找了,换了多个输入函数,一直不懂为什么n是对的而字符串就错了。原因竟然是文件名不存在,n对了只是碰巧~ 再者就是结构体的=重载函数里,把goala打成了goals,导致从第二组数据起gaols against域出错。 另外在输出的时候,%s对应的本来应该是结构体.tname,少了个tname,成为了输出结构体,这个会报这样的警告或错误[Warning] cannot pass objects of non-POD type `struct team‘ through `...‘; call will abort at runtime
4.while循环判断的是EOF,因为EOF其实也是相当于一行结束了(最后一行结束),所以在while外,应该要有一个 和while内处理getchar=‘\n‘类似 的语句。总是少了这个。上一题也是漏掉过。
吐槽,UVa 老是挂,不能及时地知道自己WA了,不能及时地调程序,效率低。有些地方自己可能也有些疑虑,AC了就AC了或回头看,WA了知道哪里有可能错,但是UVa 一挂,等你WA的时可能你就不知道哪里有可能是错因了。。下次还是自己先检查好再交吧~
Code:
//#define LOCAL #include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> #define N 35 int cmp_team(const void *_a,const void *_b); void process(char *tm1,char *tm2,int t,int gl1,int gl2); int find(char *s,int t); struct team { char tname[N]; int win,tie,los; int goals,goala; team(){ memset(tname,0,sizeof(tname)); win=tie=los=goals=goala=0; } team operator=(const char* s) { strcpy(tname,s); win=tie=los=goals=goala=0; //把goala打成了goals... return *this; } }; team tlist[35]; int main() { #ifdef LOCAL freopen("data10194.in","r",stdin);//额,把文件名写成.int,出现了奇怪的错误 freopen("data10194.out","w",stdout); #endif int n; scanf("%d",&n); //fprintf(stderr,"n:%d\n",n); char tourname[110]; getchar();//scanf与其他输入函数搭配时要特别注意~ while(n-->0) { fgets(tourname,110,stdin); //gets(tourname); int t;//team数 scanf("%d",&t); //fputs(tourname,stderr); //fprintf(stderr,"t:%d\n",t); char temp[N]; getchar();//每次把scanf改为fgets之后还是检查一下前面是否有scanf之类的吧~ for(int i=0;i<t;++i) { //scanf("%s",temp); fgets(temp,N,stdin); int len=strlen(temp); if(len>0) temp[len-1]=‘\0‘;//去除换行符 tlist[i]=temp; } int g; scanf("%d",&g); getchar(); char c; char tm1[N],tm2[N]; int ln=0; int gl1,gl2; bool flag=0; int num=0;//num while(num<g && (c=getchar())!=EOF) { if(flag==0) { if(c!=‘#‘ && c!=‘@‘) tm1[ln++]=c; else if(c==‘#‘) { tm1[ln]=‘\0‘; ln=0; scanf("%d",&gl1); } else { scanf("%d",&gl2); flag=1; } } else { if(c==‘\n‘) { tm2[ln]=‘\0‘; ln=0; flag=0; process(tm1,tm2,t,gl1,gl2); num++; //fprintf(stderr,"%s %s %d %d\n",tm1,tm2,gl1,gl2); }//进入下一行 else if(c!=‘#‘) tm2[ln++]=c; }//ifflag }//whilec if(c==EOF) { tm2[ln]=‘\0‘; process(tm1,tm2,t,gl1,gl2); }//这里遇到EOF相当于遇到‘\n‘,需要做相同的后续处理 qsort(tlist,t,sizeof(team),cmp_team); //输出 fputs(tourname,stdout); for(int i=0;i<t;++i) { int points=3*tlist[i].win+tlist[i].tie; int games=tlist[i].win+tlist[i].tie+tlist[i].los; int goaldif=tlist[i].goals-tlist[i].goala; printf("%d) %s %dp, %dg (%d-%d-%d), %dgd (%d-%d)\n",i+1,tlist[i].tname,points,games,tlist[i].win, tlist[i].tie,tlist[i].los,goaldif,tlist[i].goals,tlist[i].goala); //这里输出的第二个参数是.tname,否则结构体输出会报警告 } if(n!=0) printf("\n"); }//while //system("pause"); return 0; } int cmp_team(const void *_a,const void *_b) { team *a=(team*)_a; team *b=(team*)_b; int points_a=3*a->win+a->tie; int points_b=3*b->win+b->tie; int gd_a=a->goals-a->goala; int gd_b=b->goals-b->goala; int games_a=a->win+a->tie+a->los; int games_b=b->win+b->tie+b->los; if(points_a!=points_b) return points_b-points_a; else if(a->win!=b->win) return b->win-a->win; else if(gd_a!=gd_b) return gd_b-gd_a; else if(a->goals!=b->goals) return b->goals-a->goals; else if(games_a!=games_b) return games_a-games_b; else { char tname1[N],tname2[N]; for(int i=0;i<strlen(a->tname);++i) tname1[i]=tolower(a->tname[i]);//我不知道我为什么会写成这样:tname1[i]=tolower(tname1[i]); for(int i=0;i<strlen(b->tname);++i) tname2[i]=tolower(b->tname[i]); return strcmp(tname1,tname2); } } void process(char *tm1,char *tm2,int t,int gl1,int gl2) { int x=0,y=0; x=find(tm1,t); y=find(tm2,t); if(x<t&&y<t) {//处理结构体成员变量 if(gl1>gl2) { tlist[x].win++; tlist[y].los++;} else if(gl1==gl2) { tlist[x].tie++; tlist[y].tie++; } else { tlist[x].los++; tlist[y].win++; } tlist[x].goals+=gl1; tlist[x].goala+=gl2; tlist[y].goals+=gl2; tlist[y].goala+=gl1; } } int find(char *s,int t) {//在tlist中找teamname为s的team的下标 for(int i=0;i<t;++i) { if(strcmp(s,tlist[i].tname)==0) return i; } return t; }
原文:http://blog.csdn.net/buxizhizhou530/article/details/21817645