P1042 [NOIP2003 普及组] 乒乓球

题目描述

华华通过以下方式进行分析,首先将比赛每个球的胜负列成一张表,然后分别计算在 11 分制和 21 分制下,双方的比赛结果(截至记录末尾)。
比如现在有这么一份记录,(其中 W 表示华华获得一分,L 表示华华对手获得一分):
WWWWWWWWWWWWWWWWWWWWWWLW
在 11 分制下,此时比赛的结果是华华第一局 11 比 0 获胜,第二局 11 比 0 获胜,正在进行第三局,当前比分 1 比 1。
而在 21 分制下,此时比赛结果是华华第一局 21 比 0 获胜,正在进行第二局,比分 2 比 1。
如果一局比赛刚开始,则此时比分为 0 比 0。直到分差大于或者等于 2,才一局结束。
你的程序就是要对于一系列比赛信息的输入(WL 形式),输出正确的结果。

输入格式

每个输入文件包含若干行字符串,字符串有大写的 W 、 L 和 E 组成。其中 E 表示比赛信息结束,程序应该忽略 E 之后的所有内容。

输出格式

输出由两部分组成,每部分有若干行,每一行对应一局比赛的比分(按比赛信息输入顺序)。
其中第一部分是 11 分制下的结果,第二部分是 21 分制下的结果,两部分之间由一个空行分隔。

输入输出样例

输入#1

WWWWWWWWWWWWWWWWWWWW
WWLWE

输出#1

11:0
11:0
1:1

21:0
2:1

说明/提示

每行至多 25 个字母,最多有 2500 行。

【题目来源】

NOIP 2003 普及组第一题

思路:首先是存储字符串中字符E之前的字符(即有效字符),可以通过一个判断条件为true的死循环来不断输入字符,在循环内部对字符输入是否为E进行判断,如果是E就break退出循环。·首先进行11分制比分处理,通过循环逐个遍历字符,是W的话就让华华胜利场数加1,如果为L就让华华失败场数加1,根据题意必须至少有一位选手的比赛分数大于等于11且两位选手的分数差要大于等于2,所以把这个作为比赛结束的判断条件,在结束时输出双方比分。21赛制同理11赛制。要注意的是,有可能一场比赛都没有进行,比如输入的字符串只包含字符E,此时应直接输出0:0,也有可能上一轮比赛结束时刚好下一轮比赛要开始,那么这个时候不仅要输出上一轮的比赛分数,还要输出0:0,例如输入的字符串是WWWWWWWWWWWE,这个时候就要输出11:0和0:0,意思是说上一轮已经分出胜负,而由于比赛场数正好是11,所以下一轮比赛刚刚开始,刚开始双方比分都是0,所以0:0也要输出(只输出11:0会卡最后一个点)。最后要记得及时重置每一场的比分,以防影响下一轮比分的记录。

代码:

  1 #define _CRT_SECURE_NO_WARNINGS
  2 
  3 #include<stdio.h>
  4 #include<math.h>
  5 
  6 int num;              //一共多少个字母
  7 char input[62501];    //一共打了多少场(不包括E)
  8 int win;              //每一轮比赛赢了多少场
  9 int lose;             //每一轮比赛输了多少场
 10 
 11 //11分制比赛结果
 12 void score11()
 13 {
 14     int i;
 15     //没有比赛
 16     if (num == 0)
 17     {
 18         printf("0:0
");
 19     }
 20     for (i = 0; i < num; i++)
 21     {
 22         if (input[i] == 'W')
 23         {
 24             win++;
 25         }
 26         else if (input[i] == 'L')
 27         {
 28             lose++;
 29         }
 30         //直到分差大于或者等于 2,才一局结束。
 31         if (fabs(win - lose) >= 2)
 32         {
 33             //只要有一方比分超过11就输出比分
 34             if (win >= 11 || lose >= 11)
 35             {
 36                 printf("%d:%d
", win, lose);
 37                 //重置
 38                 win = 0;
 39                 lose = 0;
 40             }
 41         }
 42         //最后一场比赛直接输出然后结束
 43         if (i == num - 1)
 44         {
 45             printf("%d:%d
", win, lose);
 46             break;
 47         }
 48     }
 49 }
 50 
 51 //21分制比赛结果
 52 void score21()
 53 {
 54     //重置
 55     win = 0;
 56     lose = 0;
 57     printf("
");   //单独空一行
 58     //没有比赛
 59     if (num == 0)
 60     {
 61         printf("0:0");
 62     }
 63     int i;
 64     for (i = 0; i < num; i++)
 65     {
 66         if (input[i] == 'W')
 67         {
 68             win++;
 69         }
 70         else if (input[i] == 'L')
 71         {
 72             lose++;
 73         }
 74         //直到分差大于或者等于 2,才一局结束。
 75         if (fabs(win - lose) >= 2)
 76         {
 77             //只要有一方比分超过11就输出比分
 78             if (win >= 21 || lose >= 21)
 79             {
 80                 printf("%d:%d
", win, lose);
 81                 //重置
 82                 win = 0;
 83                 lose = 0;
 84             }
 85         }
 86         //最后一场比赛直接输出然后结束
 87         if (i == num - 1)
 88         {
 89             printf("%d:%d", win, lose);
 90             break;
 91         }
 92     }
 93 }
 94 
 95 int main()
 96 {
 97     char c;
 98     while (true)
 99     {
100         scanf("%c", &c);
101         if (c == 'W' || c == 'L')
102         {
103             input[num] = c;
104             num++;
105         }
106         else if (c == 'E')    //输入E时退出
107         {
108             break;
109         }
110     }
111     score11();
112     score21();
113     return 0;
114 }

开头的#define _CRT_SECURE_NO_WARNINGS是防止VS2019的scanf报错用,其他编译器可以不要这一行。

原文地址:https://www.cnblogs.com/guanrongda-KaguraSakura/p/15008544.html