原文链接Dashboard - Codeforces Round #740 (Div. 1, based on VK Cup 2021 - Final (Engine)) - Codeforces
制作不易,点个赞再走
题目描述
Alice and Borys are playing tennis.
A tennis match consists of games. In each game, one of the players is serving and the other one is receiving.
Players serve in turns: after a game where Alice is serving follows a game where Borys is serving, and vice versa.
Each game ends with a victory of one of the players. If a game is won by the serving player, it's said that this player holds serve. If a game is won by the receiving player, it's said that this player breaks serve.
It is known that Alice won aa games and Borys won bb games during the match. It is unknown who served first and who won which games.
Find all values of kk such that exactly kk breaks could happen during the match between Alice and Borys in total.
输入格式
Each test contains multiple test cases. The first line contains the number of test cases tt ( 1 \le t \le 10^31≤t≤103 ). Description of the test cases follows.
Each of the next tt lines describes one test case and contains two integers aa and bb ( 0 \le a, b \le 10^50≤a,b≤105 ; a + b > 0a+b>0 ) — the number of games won by Alice and Borys, respectively.
It is guaranteed that the sum of a + ba+b over all test cases does not exceed 2 \cdot 10^52⋅105 .
输出格式
For each test case print two lines.
In the first line, print a single integer mm ( 1 \le m \le a + b + 11≤m≤a+b+1 ) — the number of values of kk such that exactly kk breaks could happen during the match.
In the second line, print mm distinct integers k_1, k_2, \ldots, k_mk1,k2,…,km ( 0 \le k_1 < k_2 < \ldots < k_m \le a + b0≤k1<k2<…<km≤a+b ) — the sought values of kk in increasing order.
题意翻译
题目描述
Alice 和 Borys 在打网球。
网球比赛有很多局,每局有一个人发球,有一个人接发球。这样轮流交换,一人一局。
每局比赛都有一个胜者,如果胜者是发球者,那么称为保发,反之称为破发。
我们知道 Alice 赢了 a 局,Borys 赢了 b 局,但我们不知道谁先发球和每局谁赢了。
问所有可能的总破发次数。
------------------------------------------------------------------------------------------------------------
一个人发球输了,那么另一个人就是破发;
对于总场次n=a+b 由于我们不知道谁先发球,可以分奇偶讨论。
条件隐含了下列关系
a=A发球赢的次数+A破发的次数=A发球赢的次数+B发球失败的次数
b=B发球赢的次数+B破发的次数=B发球赢的次数+A发球失败的次数
A发球总次数=a发球赢的次数+a发球输的次数(B破发次数)
B发球总次数=b发球赢的次数+b发球输的次数(A破发次数)
我们枚举A发球赢的次数,根据一系列关系,推出各个值,判断是否符合条件即可
奇数时,先发的那个人,发球总场次(a+b+1)/2,后发的(a+b)/2
例如,对先发的那个进行枚举
for(int i=0; i<=(a+b+1)/2&&i<=a; i++) 即发球赢的次数要在赢的总次数和总场次范围内
int po=a-i; 先发球的破发次数就是赢的场次减去发球赢的场次
int poo=(a+b+1)/2-i; 发球总场次(a+b+1)/2,减去发球赢的,就是对方破发的
所以总破发次数可以求出 满足po+poo>=0 pob<=b
# include<iostream>
# include<algorithm>
# include<cstring>
# include<set>
using namespace std;
set<int>s;
int main ()
{
int t;
cin>>t;
while(t--)
{
int a,b;
cin>>a>>b;
if((a+b+1)/2==0)
{
for(int i=0; i<=a; i++)
{
int po=a-i;
int pob=(a+b+1)/2-i;
s.insert(po+pob);
}
}
else
{
for(int i=0; i<=(a+b+1)/2&&i<=a; i++)
{
int po=a-i;
int pob=(a+b+1)/2-i;
if(po+pob>=0&&pob<=b&&po<=a)
s.insert(po+pob);
}
for(int i=0; i<=(a+b)/2&&i<=a; i++)
{
int po=a-i;
int pob=(a+b)/2-i;
if(po+pob>=0&&pob<=b&&po<=a)
s.insert(po+pob);
}
}
cout<<s.size()<<'\n';
for(auto it:s)
{
cout<<it<<" ";
}
cout<<'\n';
s.clear();
}
return 0;
}