1 条题解

  • 0
    @ 2025-8-24 22:20:59

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar wuyonghuming
    **

    搬运于2025-08-24 22:20:59,当前版本为作者最后更新于2022-07-29 02:02:32,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


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

    • 如果其中一个球员获胜了 66 个球及以上,并且他比另一个球员至少多获胜两个球,那么这一次对决他就胜利了。
    • 此外,如果第一、二次对决的结果都是 6:6 那么将会进行一轮决赛来准确的得出一位球员获胜。
    • 当有一名球员获胜两次对决时,他就是这轮比赛的胜者,且这轮比赛结束。

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

    分析

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

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

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

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

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

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

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

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

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

    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");//有效比赛。
    

    注意事项

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

    总代码

    #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;
    }
    
    
    • 1

    信息

    ID
    5476
    时间
    1000ms
    内存
    32MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者