码迷,mamicode.com
首页 > 其他好文 > 详细

Football (aka Soccer) UVA 10194

时间:2014-08-06 11:56:31      阅读:272      评论:0      收藏:0      [点我收藏+]

标签:acm   c   uva   源代码   算法   

说说:万万没想到会在这道题上花费这么多时间。这道题其实就是比较繁琐而已,需要一个比较大的结构记录一个队伍的所有信息。原以为最难的是对比赛结果字符串的提取,但事实证明这倒还挺简单的。关键是后面对比赛结果的排序,原理相对简单,代码较庞大。需要注意的是,最后如果按队名排序是不区分大小写的,并且队名不只是英文字母!而且这里提一下C的语言特性,如果在调用一个返回字符指针的函数,且返回的是被调用函数内定义的字符数组,那样是会出错的,因为子函数调用结束后相应的资源就被释放了。要关注细节呀~哈哈~


题目:

Football (aka Soccer)

The Problem

Football the most popular sport in the world (americans insist to call it "Soccer",but we will call it "Football"). As everyone knows, Brasil is the country that have most World

足球是世界上最受欢迎的运动(美国人坚持叫它“soccer”,但我们叫它“football”)。众所周知,巴西是世界上获得世界杯冠军最多的国家(1958,1962,1970和1994,题目

Cup titles (four of them: 1958, 1962, 1970 and 1994). As our national tournament have many teams(and even regional tournaments have many teams also) it‘s a very hard

有点老....)。因为我们的国家锦标赛有很多队伍(即使区域锦标赛也有很多队伍),所以记录这些队伍和比赛的成绩就显得非常困难了。

task to keep track of standings with so many teams and games played!

So, your task is quite simple: write a program that receives the tournament name, team names and games played and outputs the tournament standings so far.

所以你的任务很简单:写一个能够接收锦标赛名称,队伍的名称以及比赛并且能够输出锦标赛到目前为止的积分情况。

A team wins a game if it scores more goals than its opponent. Obviously, a team loses a game if it scores less goals. When both teams score the same number of goals, we

如果一个队伍比对手得了更多分,那么他们将赢得比赛。显然,如果一个队伍得分少,那么他们将输掉比赛。如果两个队伍得了同样的分,

call it a tie.A team earns 3 points for each win, 1 point for each tie and 0 point for each loss.

那两队平局。一个队伍每赢一场得三分,平一场得一分,输一场得0分

Teams are ranked according to these rules (in this order):

比赛的队伍将根据下列规则排名

  1. Most points earned.得分最多
  2. Most wins.比赛胜场最多
  3. Most goal difference (i.e. goals scored - goals against)净胜球最多
  4. Most goals scored.进球最多
  5. Less games played.比赛场次最少
  6. Lexicographic order.字典序
The Input

The first line of input will be an integer N in a line alone (0 < N < 1000). Then, will follow N tournament descriptions. Each one begins with the tournament name, on a single

第一行输入是一个整数N(0<N<1000).接下来是关于N场锦标赛的描述。每场的开头一行是锦标赛名称

line. Tournament names can have any letter, digits, spaces etc. Tournament names will have length of at most 100. Then, in the next line, there will be a number T (1 < T <=

锦标赛名称可以有任意多的字母,数字,空格等待。锦标赛名称最多有100个字符那么长。接下来是一个数T(1<T<=30)

30), which stands for the number of teams participating on this tournament. Then will follow T lines, each one containing one team name. Team names may have any

代表参加锦标赛的队伍的数量。接下来T行,每行一个队伍名称。队伍的名称可能包含任何大于32的ASCII码,除了‘#’和‘@’。

character that have ASCII code greater than or equal to 32 (space), except for ‘#‘ and ‘@‘ characters, which will never appear in teamnames. No team name will have more than 30 characters.

并且没有队伍的名称会超过三十个字符。

Following to team names, there will be a non-negative integer G on a single line which stands for the number of games already played on this tournament. G will be no

队伍名称之后是一个非负整数G,代表了锦标赛中已经完成的比赛。

greater than 1000. Then, G lines will follow with the results of games played. They will follow this format:

G不会大于1000.然后接下来的G行是比赛的结果。它们将有如下的形式

team_name_1#goals1@goals2#team_name_2
For instance, the following line:
Team A#3@1#Team B
Means that in a game between Team A and Team B, Team A scored 3 goals and Team B scored 1.All goals will be non-negative integers less than 20. You may assume that

意思是在Team A和Team B之间有一场比赛,并且Team A得了3分,Team B得了1分。所有的得分是一个不超过20的非负整数。

there will not be in existent team names (i.e. all team names that appear on game results will have apperead on the team names section) and that no team will play against

可以保证每个比赛结果中出现的队伍在之前的队伍名称环节都出现过并且没有队伍会和自己比赛。

itself.


The output

For each tournament, you must output the tournament name in a single line. In the next T lines you must output the standings, according to the rules above. Notice that

对于每场锦标赛,你必须先输出一行队伍名称接下来的T行根据上述规则输出成绩。需要注意的是当出现平局时按照字典排序,此时区分大小写。

should the tie-breaker be the lexographic order, it must be done case in senstive. The output format for each line is shown bellow:

输出形式如下所示:

[a]) Team_name [b]p, [c]g ([d]-[e]-[f]), [g]gd ([h]-[i])

Sample Input

2
World Cup 1998 - Group A
4
Brazil
Norway
Morocco
Scotland
6
Brazil#2@1#Scotland
Norway#2@2#Morocco
Scotland#1@1#Norway
Brazil#3@0#Morocco
Morocco#3@0#Scotland
Brazil#1@2#Norway
Some strange tournament
5
Team A
Team B
Team C
Team D
Team E
5
Team A#1@1#Team B
Team A#2@2#Team C
Team A#0@0#Team D
Team E#2@1#Team C
Team E#1@2#Team D
Sample output

World Cup 1998 - Group A
1) Brazil 6p, 3g (2-0-1), 3gd (6-3)
2) Norway 5p, 3g (1-2-0), 1gd (5-4) 
3) Morocco 4p, 3g (1-1-1), 0gd (5-5)
4) Scotland 1p, 3g (0-1-2), -4gd (2-6)

Some strange tournament
1) Team D 4p, 2g (1-1-0), 1gd (2-1)
2) Team E 3p, 2g (1-0-1), 0gd (3-3)
3) Team A 3p, 3g (0-3-0), 0gd (3-3)
4) Team B 1p, 1g (0-1-0), 0gd (1-1)
5) Team C 1p, 2g (0-1-1), -1gd (3-4)

源代码:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
typedef struct team{//一个队伍的所有信息
 char name[35];
 int point;
 int game_played;
 int win,loss,tie;
 int goal_differ,goal_scored,goal_against;
}TEAM;

TEAM teams[30+5];
char tournament[100+5];
char result[100];
int N,T,Q;

void handle_str(char*,char*,char*,int*,int*);//处理比赛结果的字符串
void add_result(char*,char*,int,int);//将比赛结果添加到相应结点
void sort();
void output_result();
char* convert(char*);

int main(){
 int i,j,k;
 char Team_A[35],Team_B[35];
 int score_A,score_B;
 //freopen("D:\data.txt","r",stdin);
 scanf("%d\n",&N);

 while(N--){
    gets(tournament);
    scanf("%d\n",&T);
    for(i=0;i<T;i++){//初始化队伍信息
        gets(teams[i].name);
        teams[i].point=teams[i].game_played=0;
        teams[i].win=teams[i].loss=teams[i].tie=0;
        teams[i].goal_differ=teams[i].goal_scored=teams[i].goal_against=0;
    }

    scanf("%d\n",&Q);
    for(i=0;i<Q;i++){
        gets(result);
        handle_str(result,Team_A,Team_B,&score_A,&score_B);//处理比赛结果
        add_result(Team_A,Team_B,score_A,score_B);//添加比赛结果
    }
    sort();

    output_result();
    if(N) putchar('\n');
 }

 return 0;
}

void output_result(){//输出比赛结果
  int i;

  printf("%s\n",tournament);
  for(i=0;i<T;i++){
    printf("%d) %s %dp, %dg ",i+1,teams[i].name,teams[i].point,teams[i].game_played);
    printf("(%d-%d-%d), ",teams[i].win,teams[i].tie,teams[i].loss);
    printf("%dgd (%d-%d)\n",teams[i].goal_differ,teams[i].goal_scored,teams[i].goal_against);
  }
  return;
}

void add_result(char*Team_A,char*Team_B,int score_A,int score_B){//添加比赛结果
 int i;

 for(i=0;i<T;i++)
 if(strcmp(Team_A,teams[i].name)==0){
    teams[i].game_played++;
    teams[i].goal_differ+=score_A-score_B;
    teams[i].goal_scored+=score_A;
    teams[i].goal_against+=score_B;
    if(score_A>score_B){
        teams[i].point+=3;
        teams[i].win++;
    }
    else if(score_A==score_B){
        teams[i].point+=1;
        teams[i].tie++;
    }
    else
        teams[i].loss++;
 }
 else if(strcmp(Team_B,teams[i].name)==0){
    teams[i].game_played++;
    teams[i].goal_differ+=score_B-score_A;
    teams[i].goal_scored+=score_B;
    teams[i].goal_against+=score_A;
    if(score_B>score_A){
        teams[i].point+=3;
        teams[i].win++;
    }
    else if(score_A==score_B){
        teams[i].point+=1;
        teams[i].tie++;
    }
    else
        teams[i].loss++;
 }

 return ;
}

void handle_str(char* result,char*Team_A,char*Team_B,int*score_A,int*score_B){//处理结果字符串
  int i,pos;
  int A=0,B=0;
  i=pos=0;
  while(result[pos]!='#')
    Team_A[i++]=result[pos++];
  Team_A[i]='\0';

  pos++;
  while(isdigit(result[pos]))
    A=A*10+result[pos++]-'0';
  *score_A=A;

  pos++;
  while(isdigit(result[pos]))
    B=B*10+result[pos++]-'0';
  *score_B=B;

  pos++;
  i=0;
  while(result[pos]!='\0')
    Team_B[i++]=result[pos++];
  Team_B[i]='\0';
}

void sort(){
  int i,j;
  TEAM temp;
  char team_A[35],team_B[35];
  for(i=1;i<T;i++)
  for(j=i;j>0;j--){//按题目所给的规则进行排序
    if(teams[j].point<teams[j-1].point)
        break;
    else if(teams[j].point==teams[j-1].point){
        if(teams[j].win<teams[j-1].win)
        break;
        else if(teams[j].win==teams[j-1].win){
            if(teams[j].goal_differ<teams[j-1].goal_differ)
                break;
            else if(teams[j].goal_differ==teams[j-1].goal_differ){
                if(teams[j].goal_scored<teams[j-1].goal_scored)
                    break;
                else if(teams[j].goal_scored==teams[j-1].goal_scored){
                    if(teams[j].game_played>teams[j-1].game_played)
                      break;
                    else if(teams[j].game_played==teams[j-1].game_played){
                        strcpy(team_A,teams[j].name);
                        strcpy(team_B,teams[j-1].name);
                        if(strcmp(convert(team_A),convert(team_B))>=0)//注意!不区分大小写
                            break;
                    }
                }
            }
        }
    }

    temp=teams[j];
    teams[j]=teams[j-1];
    teams[j-1]=temp;
  }
}

char*convert(char*team){
  int i=0;
  while(team[i]){
    if(isalpha(team[i]))//队名并非都为字母
    team[i]=tolower(team[i]);
    i++;
  }
  return team;
}











Football (aka Soccer) UVA 10194,布布扣,bubuko.com

Football (aka Soccer) UVA 10194

标签:acm   c   uva   源代码   算法   

原文地址:http://blog.csdn.net/u011915301/article/details/38380433

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!