题意:就是给定一个整数序列,让你在这个序列中找到一个子集{a, b, c, d}吗,满足a + b + c = d且d最大,若不存在这样的集合输出 “no solution”;
题解:这题如果用暴力枚举,O(n^4),n最大为1000,必然TLE。所以要拆分枚举,
a + b = c - d枚举 a , b 然后c - d的值二分搜索 和 a+ b比较直到 a+b=c-d;
当然 二分的条件是 有序序列 , 先排个序就可以,以 增序排列,这样 逆序枚举 得到的满足条件的d一定是最大的..
上代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
#define debug 0
#define M(a, b) memset(a, b, sizeof(a))
const int maxn = 1000 + 5;
const int inf = -0x3f3f3f3f;
int n, m; int a[maxn];
void Do() {
int ans = inf;
for (int i = n; i >= 1; i--)
{
for (int j = n; j >= 1; j--)
{
if (i == j)
continue;
int temp = a[i] - a[j];
int l = 1, r = j - 1;
while (l < r)
{
if (temp > a[l] + a[r])
{
l++;
}
else if (temp < a[l] + a[r])
{
r--;
}
else {
ans = max(ans, a[i]);
}
if (ans != inf)
break;
}
if (ans != inf)
break;
}
if (ans != inf)
break;
}
if (ans != inf)
printf("%d\n", ans);
else
printf("no solution\n");
}
int main() {
#if debug
freopen("in.txt", "r", stdin);
#endif //debug
// M(dp, 0);
while (~scanf("%d", &n), n)
{
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
sort(a + 1, a + 1 + n);
Do();
}
return 0;
}