传送门UVa 10194 - Football (aka Soccer)
乍一看这题瞬间就不想写了, 感觉好像很麻烦的样子. 但是我还是一遍一遍对自己说: 以后碰到比这个麻烦的题不知要多多少, 现在这题可以不做, 以后怎么办(╯‵□′)╯ ┴─┴ .
于是我还是硬着头皮看了下来.
题意是让你统计各个球队的进球数, 失球数等, 然后按一定顺序输出.
我的算法是建一个结构体数组, 存放每个队的情况, 然后逐句写入进球, 失球, 最后用qsort排序输出.
需要注意的地方:
1.球数可以是两位数, 用字符串处理的要小心了.
2.最后按字典序排序时是不分大小写的, 我用了strcasecmp这个函数. 这个函数是linux下的, 作用是不分大小写比较两个字符串, 好像因为oj是搭建在linux环境下的, 所以可以编译通过. windows下有一个相同功能的函数stricmp, 但是我用这个函数提交的时候就CE了.
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
using namespace std;
void Initial(struct country cont[], int n);
void Save(char tempcont[], int win, int lose, int n, struct country cont[]);
int comp(const void *_a, const void *_b);
typedef struct country
{
int win, lose, ties, cnt, points, winnum, losenum;
char name[200];
};
int main()
{
freopen("input.txt", "r", stdin);
country cont[40];
int wocao = 0;
int i, j;
int T, n, k;
int a, b, c;
int win, lose;
int cnt = 0;
char ch;
scanf("%d", &T);
getchar();
char temp[200], tempcont[100];
memset(temp, 0, sizeof(temp));
memset(tempcont, 0, sizeof(tempcont));
while (T--)
{
if (wocao != 0) //输出空行
printf("\n");
wocao++;
Initial(cont, n); //初始化每个国家的信息.
char gamename[100];
fgets(gamename, 100, stdin); //读取比赛的名字.
printf("%s", gamename);
scanf("%d", &n);
getchar();
for (i = 0; i < n; i++) //读入每个队伍的名字.
for (j = 0; (ch = getchar()) != '\n'; j++)
cont[i].name[j] = ch;
scanf("%d", &k);
getchar();
for (i = 0; i < k; i++) //开始统计数据, 我采用的是挨个字符读取的方法
{
while ((ch = getchar()) != '#')
tempcont[cnt++] = ch;
scanf("%d", &win);
getchar(); //读取@
scanf("%d", &lose);
getchar(); //读取#
Save(tempcont, win, lose, n, cont); //找到对应的国家并记录.
memset(tempcont, 0, sizeof(tempcont));
int tempnum = win; //对于后一个队伍, 胜负球数相反. 交换胜负球数
win = lose;
lose = tempnum;
cnt = 0;
while ((ch = getchar()) != '\n')
tempcont[cnt++] = ch;
cnt = 0;
Save(tempcont, win, lose, n, cont);
memset(tempcont, 0, sizeof(tempcont));
}
qsort(cont, n, sizeof(cont[0]), comp);
for (i = 0; i < n; i++)
printf("%d) %s %dp, %dg (%d-%d-%d), %dgd (%d-%d)\n", i + 1, cont[i].name,
cont[i].points, cont[i].cnt, cont[i].winnum, cont[i].ties, cont[i].losenum, cont[i].win - cont[i].lose, cont[i].win, cont[i].lose);
}
return 0;
}
void Save(char tempcont[], int win, int lose, int n, struct country cont[])
{
int i, j;
for (i = 0; i < n; i++)
{
if (strcmp(tempcont, cont[i].name) == 0) //找到相同名字的队伍, 计入各种数据
{
cont[i].win += win;
cont[i].lose += lose;
if (win > lose)
{
cont[i].points += 3;
cont[i].winnum++;
}
else if (win == lose)
{
cont[i].ties++;
cont[i].points += 1;
}
else
cont[i].losenum++;
cont[i].cnt++;
break;
}
}
}
void Initial(struct country cont[], int n) //初始化结构体数组.
{
for (int i = 0; i < 40; i++)
{
cont[i].cnt = 0;
cont[i].lose = 0;
cont[i].losenum = 0;
cont[i].points = 0;
cont[i].ties = 0;
cont[i].win = 0;
cont[i].winnum = 0;
memset(cont[i].name, 0, sizeof(cont[i].name));
}
}
int comp(const void *_a, const void *_b) //排序的条件
{
country *a = (country *)_a;
country *b = (country *)_b;
if (a->points != b->points)
return (b->points - a->points);
else if ((a->winnum != b->winnum))
return (b->winnum - a->winnum);
else if ((a->win - a->lose) != (b->win - b->lose))
return ((b->win - b->lose) - (a->win - a->lose));
else if (a->win != b->win)
return (b->win - a->win);
else if (a->cnt != b->cnt)
return (a->cnt - b->cnt);
else
return (stricmp(a->name, b->name));
}