题解 P6459 [COCI2006-2007#5] TENIS

· · 题解

题目描述中有一些比较重要的部分,如下。

根据上述题目要求,有了以下的分析。

分析

1.不可以出现平局,平局是无效比赛。

2.如果这场比赛已经有结果了,但是他们又进行了一次比赛,也就是说他们进行了 4 次以上的比赛,是无效比赛。

3.如果判断完一行的比赛结果,发现没有任何一人获胜两场,说明比赛没有结束,是无效比赛。

4.如果有一个人得了 6 分,分数比另外一个人高,但是另外一人得了 5 分,不符合一个球员获胜了 6 个球及以上,并且他比另一个球员至少多获胜两个球,是无效比赛。

5.如果有一个人获胜了 3 场及以上,不符合当有一名球员获胜两次对决时,他就是这轮比赛的胜者,且这轮比赛结束。因为当获胜 2 场的时候比赛已经结束了。

6.如果第一、二次对决的结果都是 6:6 那么将会进行一轮决赛来准确的得出一位球员获胜。这里的决赛不是指进行下一轮对决,而是只打一次,进行到 6:77:6 就可以结束这一次对决了,所以前两轮的 6:77:6 是有效比赛。但是 6:6 仍为无效比赛。

7.另外还要判断一个特殊的球员 federer 如果他输掉了任意一次对决,这次比赛就是无效的。

8.如果有一个球员得了 8 分及以上,是无效比赛,因为比赛进行到 6:6 就最多再比一场,或者一个球员得 5 分,另一个得 6 分,得 6 分的再赢一次,结束这一次对决。所以,不可能得到 8 分及以上的分数。

9.除了 6:6 进行决赛之后结束比赛,必须领先对手两个球以上,而且要达到 6 分。

10.只要有任意一次对决是无效的,整场比赛就是无效的。

实现

最主要的代码分成两块。

1.输入,存储数据。

2.判断比赛是否有效。

处理

每次取一整行,通过非数字的字符隔开比分。

string st;
int scr[21],cnt=0;//这里的scr记录分数,cnt计入数字数量。
bool p=false;//这里的p判断上一个字符是不是数字,如果是为true,不是为false。如果上一个不是数字,而这一个是,cnt需要加一。
getline(cin,st);//输入一整行。
for(int i=0;i<int(st.size());i++)
{
    if(st[i]>='0'&&st[i]<='9'&&p==false)
        scr[++cnt]=st[i]-'0',p=true;
    else if(st[i]>='0'&&st[i]<='9'&&p==true)
        scr[cnt]=scr[cnt]*10+st[i]-'0';
    else
        p=false;
}

判断

int x=0,y=0,z=0,xy=0;//x,y,z分别记录第一个人获胜次数,第二个人获胜次数,平局数。xy记录是否有无效场。
for(int i=1;i<=cnt/2;i++)
{
    string aa=a,bb=b;//这里假设比赛都是有效的,因为后面会进行判断是否有效,只要有不符合的,最后会输出ne。
    x+=scr[i*2-1]>scr[i*2];
    y+=scr[i*2-1]<scr[i*2];
    z+=scr[i*2-1]==scr[i*2];
    if(scr[i*2-1]<scr[i*2])//默认大的在前小的在后,方便后面的比较。
    {
        swap(scr[i*2-1],scr[i*2]);
        swap(aa,bb);
    }//交换完成后,前面的应是较大数,后面的应是较小数。
    if(bb=="federer"||//如果federer输了。
    (scr[i*2-1]==6&&scr[i*2]==5)||//出现6:5。
    (scr[i*2-1]-scr[i*2]>2&&i>=7)||//出现了较高者为7及以上但是高于对方3分及以上的。
    (scr[i*2-1]>=7&&i>2&&scr[i*2-1]!=scr[i*2]+2)||//不是前两场就进行决赛的。
    (scr[i*2-1]!=6&&(!(scr[i*2-1]==7&&i<3))&&(!(scr[i*2-1]>=7&&i==3))))//不以符合规定的分数结束的。
        xy=3;//直接标记为无效。
}
if(z||xy==3||(x!=2&&y!=2)||(x>=2&&y>=2))//如果出现无效局,比赛未结束或者多比的。
    puts("ne");//判为无效比赛。
else
    puts("da");//有效比赛。

注意事项

每次取一行,而输入 n 未换行就取一行会把 n 输入进去。所以输入 n 之后需要再取一次。

总代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string a,b,l;
    cin>>a>>b;
    int n;
    cin>>n;
    getline(cin,l);
    while(n--)
    {
        string st;
        int scr[21],cnt=0;
        bool p=false;
        getline(cin,st);
        for(int i=0;i<int(st.size());i++)
        {
            if(st[i]>='0'&&st[i]<='9'&&p==false)
                scr[++cnt]=st[i]-'0',p=true;
            else if(st[i]>='0'&&st[i]<='9'&&p==true)
                scr[cnt]=scr[cnt]*10+st[i]-'0';
            else
                p=false;
        }
        int x=0,y=0,z=0,xy=0;
        for(int i=1;i<=cnt/2;i++)
        {
            string aa=a,bb=b;
            x+=scr[i*2-1]>scr[i*2];
            y+=scr[i*2-1]<scr[i*2];
            z+=scr[i*2-1]==scr[i*2];
            if(scr[i*2-1]<scr[i*2])
            {
                swap(scr[i*2-1],scr[i*2]);
                swap(aa,bb);
            }
            if(bb=="federer"||
            (scr[i*2-1]==6&&scr[i*2]==5)||
            (scr[i*2-1]-scr[i*2]>2&&i>=7)||
            (scr[i*2-1]>=7&&i>2&&scr[i*2-1]!=scr[i*2]+2)||
            (scr[i*2-1]!=6&&(!(scr[i*2-1]==7&&i<3))&&(!(scr[i*2-1]>=7&&i==3))))
                xy=3;
        }
        if(z||xy==3||(x!=2&&y!=2)||(x>=2&&y>=2))
            puts("ne");
        else
            puts("da");
    }
    return 0;
}