UVa 10194 足球

题意:有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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值