AtCoder Beginner Contest 093 D - Worst Case

本文通过分析比赛得分问题,提出了一种寻找低于指定分数最大可能人数的方法。文章详细阐述了不同得分组合下的规律,并给出了相应的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在比赛时,我一直在找这道题的数学方法,知道应该从某个次小的数开始数总共比高桥分数少的人数,但是总结不出完善的情况。看了解题报告后思路通了些,写出了正确的代码。

重新写的代码如下:

#include <stdio.h>
#include <math.h>

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		long long a,b,c,d,e;
		scanf("%lld%lld",&a,&b);
		if(a==b)
			printf("%lld\n",2*a-2);
		else
		{
			d=a>b?a:b;
			e=a<b?a:b;
			if(d-e==1)
				printf("%lld\n",2*e-2);
			else
			{
				for(c=sqrt(a*b+0.5);c*c<a*b;c++);
				c--;
				if(c*(c+1)>=b*a)
					printf("%lld\n",2*c-2);
				else
					printf("%lld\n",2*c-1);
			}
		}
	}
	return 0;
 } 

这道题感觉没什么算法可言,纯粹的找规律,总结情况吧。题目要我们找分数低于高桥的最大可能人数,我开始以为总分是第一场比赛和第二场比赛的分数之和,推了一段时间才明白原来是分数之积。结合解题报告,对题目的分析如下:

设高桥在第一场的得分为A,在第二场的得分为B,并且A<=B(因为正反都是一样的),有如下几种情况:

  1. 如果A=B,答案是2A-2,因为(A-1)*(A+1)=A*A-1<A*A,所以只要从任意一个A开始往下找A-1,另一个往上找A+1,依此类推,则有(1,2A-1),· · · ,(A-1,A+1),(A+1,A-1),· · · , (2A -1, 1) 。所以结果是2A-2。
  2. 如果A+1=B,答案是2A-2,因为(A+2)*(A-1)=A*A+A-2<A*(A+1)=A*A+A,所以只要从A开始往下找A-1,B往上找A+2(B+1),依此类推,则有(1,2A), · · · ,(A-1,A+2),(A+2,A-1),· · · ,(2A,1) 。所以结果是2A-2。
  3. 于其他情况时,令C为满足C*C<A*B最大的整数:
  • 如果C*(C+1)>=A*B,答案是2C-2,因为C*C<A*B,而C*(C+1)>=A*B,所以C可以类似地看作第一种情况中的A来处理,不过此处可从第一场比赛的C-1开始往下找,也可以从第二场比赛的C开始往下找(但是,因为C-1中有个是A,所以从第二场比赛的C开始往下找),依此类推,则有(1,A+B-1), · · · ,(A-1,B +1),(A+1,2C-A-1),· · · ,(C,C),· · · ,(2C-1,1) ,其中的2C-A-1为C+(C-(A+1))。所以答案是2C-2。
  • 如果C*(C+1)<A*B,答案是2C-1,因为C为满足C*C<A*B最大的整数而C*(C+1)<A*B,所以同理此处可从第一组或第二组的C开始往下找(但是,因为第一组的C中有一个是A,所以从第二场比赛的C开始往下找),依此类推,则有(1,A+B-1), · · · , (A-1,B+1), (A+1,2C-A), · · · ,(C,C+1),(C+1,C), · · · ,(2C,1),其中的2C-A为C+1-(C-(A+1))。所以答案为2C-1。

在实现代码的时候,我最开始c初始化为0,会导致TLE。参考了下别人的AC代码,发现直接令C等于sqrt(AB)就行,真是妙。


存疑:解题报告中有两句话不是很理解:(Note that one of "the top C - 1 places in the first contest" is Takahashi, we shouldn’t count him.) 和(Note that one of "the top places in the first contest" is Takahashi, we shouldn’t count him.) ,分别属于第三种情况里的第一二种情况。解决了这个疑点才能完善所有情况。(已解决,加入括号中)


ps:

一般TLE出现的情况有以下几种:
  1. 死循环
  2. 算法效率较低
  3. 常数较大
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值