CodeForces - 1313B Different Rules(数学+思维)

Iria ·
更新时间:2024-09-20
· 723 次阅读

题目链接:点击查看

题目大意:一共有 n 个人,进行两轮比赛,假设第一轮比赛的名次为 x ,第二轮的名次为 y ,那么这个人的得分为 x + y ,最后的排位会按照得分的非严格升序排列,有一个人在第一轮的名次为 x ,第二轮的名次为 y ,问这个人最终最好的名次和最差的名次分别是多少

题目分析:个人感觉难度大于C题的一道B题。。

参考视频:https://www.bilibili.com/video/av91242850?p=2

需要注意好排位的标准是非严格升序,如果有三个人的得分相同,那么这三个人的排位都为并列第三,而非并列第一,首先要理解这里,正好说一下如何构建最差的名次吧,接上面的话继续来说,因为 n 个人总得分之和是不变的,所以我们只需要尽可能多的构造与这个人的比分相同的分数就好了,而不需要构造比分比他小的分数,因为没必要,最终效果都会让这个人的排位往后靠,比如这个人的得分为 3 ,我们如果想让这个人排位第三的话,1 2 3 和 3 3 3 的效果是一样的,所以我们现在的目标变为了如何构造尽可能多的,分数与 x + y 相同的分数,假设此时第一轮的排名是升序的,为1,2,3...x+y-1,那么对应着第二轮的分数为 x+y-1,x+y-2...2,1,这样能够使得前面 x+y-1 个人的最终分数都等于 x + y,也就是包含这个人在内的x+y-1个人并列第 x + y - 1 ,这也是最坏情况了

再说回最好情况,也就是让大于 x + y 的人尽可能多,分情况讨论一下,如果 x + y n 时,既然一定不能保证在第一名了,那么我们就让第一名的那个人两次排名之和尽可能小就好了,即让一个人两次都获得第一名,此时我们可以忽略掉第一名的存在了,让所有之前的排位都向前进一位,也就是 x 变为了 x - 1,y 变为了 y - 1,n 变为了 n - 1 ,我们需要不断重复这个步骤,直到回到第一种情况为止,假设需要一直操作 t 次,则当 x - t + y - t = n - t 时停止操作,可以解得 t = x + y - n ,也就是说有 x + y - n 个人会在这个人的前面,那么这个人最好的排位也就是 x + y - n + 1 了

记得维护一下边界情况就好了

代码:

#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long LL; typedef unsigned long long ull; const int inf=0x3f3f3f3f; const int N=1e3+100; int main() { #ifndef ONLINE_JUDGE // freopen("input.txt","r",stdin); // freopen("output.txt","w",stdout); #endif // ios::sync_with_stdio(false); int w; cin>>w; while(w--) { LL n,x,y; scanf("%lld%lld%lld",&n,&x,&y); printf("%lld %lld\n",min(n,max(1LL,x+y-n+1)),min(x+y-1,n)); } return 0; }
作者:Frozen_Guardian



CodeForces 数学 rules

需要 登录 后方可回复, 如果你还没有账号请 注册新账号