先给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; }