HDU 5461 Largest Point 水题

12 篇文章 0 订阅

先给n,a,b。然后有n个数,t1,t2,t3,,,,tn,然后找到合适的ti和tj(i!=j),使得a*ti^2+b*tj最大。

a,b,和ti都属于[-10^6,10^6]。

不妨设c=a*ti^2+b*tj。a>0时,ti的绝对值越大,c越大,a<0时,ti的绝对值越小,c越大。b>0时,tj的值越大,c越大,b<0时,tj的绝对值越小,c越大。

有了这个之后,我们根据a的正负,ti取绝对值最大或最小的那个数,根据b的正负,tj取最大或最小的那个数。

当然,肯定不能直接这么取,当ti和tj取到的是同一个数时,肯定是非法的,这时候,就需要一个取次大/次小的,另一个还是原来的最大/最小的。至于是哪个取次大/次小的呢,我们把两个都试一下,哪个得到的c大就是哪个咯。

当然,还有a或者b等于0的情况,两个都等于0,答案肯定是0,只有一个等于0,那么它对应的t也是随便取了,因为n>=2,所以我们只需要把另一个t按对应的规则取最大/最小即可得到c。

所以,我们只需要8个数,最大值,次大值,最小值,次小值,绝对值最大值,绝对值次大值,绝对值最小值,绝对值次小值。

我们如何判断其中两个是不是同一个数呢?就需要记录他们的位置(当然不能简单地通过值来判断是否是同一个数咯,因为值可能是重复的),所以还需要另外8个数,记录他们对应的位置,根据位置是否相同即可知道是不是同一个数。

然后,就可以啦。


代码:

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 5000005
#define maxt 1000002
//int t[maxn];
int main()
{
	//freopen("input.txt", "r", stdin);
	int T;
	scanf("%d", &T);
	for (int kase = 1; kase <= T; ++kase)
	{
		int n, a, b;
		long long tmp, tmp1;
		long long ans = 0;
		long long max1 = -maxt, max2 = -maxt, min1 = maxt, min2 = maxt, amax1 = -1, amax2 = -1, amin1 = maxt, amin2 = maxt;
		int max1p = -1, max2p = -1, min1p = -1, min2p = -1, amax1p = -1, amax2p = -1, amin1p = -1, amin2p = -1;
		scanf("%d%d%d", &n, &a, &b);
		for (int i = 0; i < n; ++i)
		{
			scanf("%I64d", &tmp);
			tmp1 = abs(tmp);
			if (tmp > max1)
				max2 = max1, max2p = max1p, max1 = tmp, max1p = i;
			else if (tmp > max2)
				max2 = tmp, max2p = i;
			if (tmp < min1)
				min2 = min1, min2p = min1p, min1 = tmp, min1p = i;
			else if (tmp < min2)
				min2 = tmp, min2p = i;
			if (tmp1 > amax1)
				amax2 = amax1, amax2p = amax1p, amax1 = tmp1, amax1p = i;
			else if (tmp1 > amax2)
				amax2 = tmp1, amax2p = i;
			if (tmp1 < amin1)
				amin2 = amin1, amin2p = amin1p, amin1 = tmp1, amin1p = i;
			else if (tmp1 < amin2)
				amin2 = tmp1, amin2p = i;
		}
		//printf("%I64d %I64d %I64d %I64d %I64d %I64d %I64d %I64d \n", max1, max2, min1, min2, amax1, amax2, amin1, amin2);
		//printf("%d %d %d %d %d %d %d %d \n", max1p, max2p, min1p, min2p, amax1p, amax2p, amin1p, amin2p);
		if (a == 0)
		{
			if (b > 0)
				ans = b*max1;
			else if (b < 0)
				ans = b*min1;
			else
				ans = 0;
		}
		if (b == 0)
		{
			if (a > 0)
				ans = a*amax1*amax1;
			else if (a < 0)
				ans = a*amin1*amin1;
			else
				ans = 0;
		}
		if (a > 0)
		{
			if (b > 0)
			{
				if (amax1p != max1p)
					ans = a*amax1*amax1 + b*max1;
				else
				{
					long long a1 = a*amax1*amax1 + b*max2;
					long long a2 = a*amax2*amax2 + b*max1;
					ans = max(a1, a2);
				}
			}
			else if (b < 0)
			{
				if (amax1p != min1p)
					ans = a*amax1*amax1 + b*min1;
				else
				{
					long long a1 = a*amax1*amax1 + b*min2;
					long long a2 = a*amax2*amax2 + b*min1;
					ans = max(a1, a2);
				}
			}
		}
		else if (a < 0)
		{
			if (b > 0)
			{
				if (amin1p != max1p)
					ans = a*amin1*amin1 + b*max1;
				else
				{
					long long a1 = a*amin1*amin1 + b*max2;
					long long a2 = a*amin2*amin2 + b*max1;
					ans = max(a1, a2);
				}
			}
			if (b < 0)
			{
				if (amin1p != min1p)
					ans = a*amin1*amin1 + b*min1;
				else
				{
					long long a1 = a*amin1*amin1 + b*min2;
					long long a2 = a*amin2*amin2 + b*min1;
					ans = max(a1, a2);
				}
			}
		}
		printf("Case #%d: %I64d\n", kase, ans);
	}
	//while (1);
	//system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值