题目描述
题目大意:有一场比赛分2轮比赛,每一轮比赛没有并列名次(看错题目的我心痛,看成同一个人在两轮比赛排名不同,认真看题啊! ),比赛总名次为小于等于你两轮排名和的选手的数量,如:你两轮排名分别为
4
4
4,
3
3
3那么你的排名为两轮排名和小于等于7的选手数包括自己。
现在给你给出参赛选手人数,某一选手两轮的名次,求出你可能的最高和最低排名为多少:
思路:有一点贪心的味道。
最低排名贪心思路
让尽可能多的人与你同分,名次花费代价最小 假设你的排名为
x
,
y
x, y
x,y
x x x | y y y |
---|---|
1 1 1 | x + y − 1 x+y-1 x+y−1 |
3 3 3 | x + y − 2 x+y-2 x+y−2 |
4 4 4 | x + y − 3 x+y-3 x+y−3 |
5 5 5 | x + y − 4 x+y-4 x+y−4 |
. . . ... ... | . . . ... ... |
x + y − 1 x+y-1 x+y−1 | 1 1 1 |
拼
凑
方
案
拼凑方案
拼凑方案
又因为
x
+
y
−
1
>
=
x
x+y-1>=x
x+y−1>=x 所以 x,y这个组合包含在
1
1
1~
(
x
+
y
−
1
)
(x+y-1)
(x+y−1)中,所以,最低可能排名为:
m
i
n
(
x
+
y
−
1
,
n
)
min(x+y-1,n)
min(x+y−1,n);
最高可能排名思路
分两种情况:
case 1: x + y < = n x+y<=n x+y<=n
x x x | y y y |
---|---|
1 1 1 | n n n |
2 2 2 | n − 1 n-1 n−1 |
3 3 3 | n − 2 n-2 n−2 |
4 4 4 | n − 3 n-3 n−3 |
. . . ... ... | . . . ... ... |
n n n | 1 1 1 |
当然:可能有疑惑?排名为
n
+
1
n+1
n+1的人有
n
n
n个,外加
x
,
y
x,y
x,y,岂不是人数变为
n
+
1
n+1
n+1了
没关系,我们将x,y从中剔除,在相应平移也能得出当
x
+
y
<
=
n
x+y<=n
x+y<=n时,最高排名为1的结论
case 2: x + y > n x +y>n x+y>n
稍微灵活转变一下,当某一轮为
1
1
1~
(
x
+
y
−
n
)
(x+y-n)
(x+y−n)的人我们无论如何配都无法让他的排名和高于我们,所以我们让低名次经量为抬高我们的名次做贡献,所以某轮排名为
1
1
1~
(
x
+
y
−
n
)
(x+y-n)
(x+y−n)的我们让他另一轮也为同样的名次,然后当没有这些人了,我们的排名更新为 X Y 人数更新为 N 且 X+Y<=N 转化为case 1,排名为
m
i
n
(
n
,
x
+
y
−
n
+
1
)
min(n,x+y-n+1)
min(n,x+y−n+1)
x
+
y
−
n
x+y-n
x+y−n推导:
1 1 1 | 1 1 1 |
---|---|
2 2 2 | 2 2 2 |
. . . ... ... | . . . ... ... |
x x x | y y y |
设删除的人为
t
t
t则case2->case1的临界为:
x
−
t
+
y
−
t
=
n
−
t
x-t+y-t=n-t
x−t+y−t=n−t 解的
t
=
x
+
y
−
n
t=x+y-n
t=x+y−n
附代码:
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int m;
cin>>m;
while(m--)
{
int n,x,y;
cin>>n>>x>>y;
int les=min(x+y-1,n);
int bg;
if(x+y<=n)bg=1;
else bg=min(x+y-n+1,n);
cout<<bg<<" "<<les<<endl;
}
return 0;
}