一、题目大意
我们有1000个数字组成的集合,从中找出所有满足 a + b + c = d 的所有情况(a b c d 是集合中下标不同的四个元素),输出最大的d即可。
二、解题思路
1、a + b + c = d; a + b = c - d,我们把数组的任意两个下标不同元素的和都计算出来,放在数组AB里,同时记录下两个相加元素的下标,之后跟据两个元素的和来对这个数组AB排序。
2、然后循环集合中所有的元素,枚举任意两个下标不同的元素c d的差(num[d]-num[c]),之后去AB数组里二分num[d]-num[c](找到不小于num[d]-num[c]的第一个元素下标idx),如果AB[idx].sum等于num[d]-num[c]且四个元素的下标都不同的话,就保存更新ans,下标存在相同的话,判断下AB数组下一个和是不是也是num[d]-num[c],是的话就顺着AB数组往下找,直到AB[idx++]!=num[d]-num[c],就计算下一个(num[d]-num[c])。
三、代码
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
struct Node
{
ll sum;
int idx1, idx2;
Node(ll sum = 0LL, int idx1 = 0, int idx2 = 0) : sum(sum), idx1(idx1), idx2(idx2) {}
};
// a+b+c=d,a+b=d-c
Node ab[1000007];
ll num[1007], ans;
int n, abLen;
void input()
{
ans = -0x3f3f3f3f3f3f3f3fLL;
for (int i = 0; i < n; i++)
{
scanf("%lld", &num[i]);
}
}
bool compareNode(const Node &a, const Node &b)
{
return a.sum < b.sum;
}
void calcAB()
{
abLen = 0;
for (int a = 0; a < n; a++)
{
for (int b = (a + 1); b < n; b++)
{
ab[abLen].idx1 = a;
ab[abLen].idx2 = b;
ab[abLen++].sum = num[a] + num[b];
}
}
sort(ab, ab + abLen, compareNode);
ab[abLen].sum = 0x3f3f3f3f3f3f3f3fLL;
ab[abLen].idx1 = -1;
ab[abLen].idx2 = -1;
}
int binarySearch(ll number)
{
int l = -1, r = abLen + 1;
while ((l + 1) < r)
{
int mid = (l + r) / 2;
if (ab[mid].sum < number)
{
l = mid;
}
else
{
r = mid;
}
}
return (l + 1);
}
bool judgeDistinct(Node node1, Node node2)
{
if (node1.idx1 == node2.idx1 || node1.idx1 == node2.idx2)
{
return false;
}
if (node1.idx2 == node2.idx1 || node1.idx2 == node2.idx2)
{
return false;
}
return true;
}
void solve()
{
Node cd;
for (int d = 0; d < n; d++)
{
for (int c = (d + 1); c < n; c++)
{
cd.sum = num[d] - num[c];
cd.idx1 = c;
cd.idx2 = d;
int idx = binarySearch(cd.sum);
while (idx < abLen && ab[idx].sum == cd.sum)
{
if (judgeDistinct(ab[idx], cd))
{
ans = max(ans, num[d]);
break;
}
idx++;
}
}
}
for (int d = n - 1; d >= 0; d--)
{
for (int c = d - 1; c >= 0; c--)
{
cd.sum = num[d] - num[c];
cd.idx1 = c;
cd.idx2 = d;
int idx = binarySearch(cd.sum);
while (idx < abLen && ab[idx].sum == cd.sum)
{
if (judgeDistinct(ab[idx], cd))
{
ans = max(ans, num[d]);
break;
}
idx++;
}
}
}
}
int main()
{
while (true)
{
scanf("%d", &n);
if (n == 0)
{
break;
}
input();
calcAB();
solve();
if (ans == (-0x3f3f3f3f3f3f3f3fLL))
{
printf("no solution\n");
}
else
{
printf("%lld\n", ans);
}
}
return 0;
}