uva 10125 - Sumsets

时间:2024-08-10 23:04:14

题意:

输入n,然后输入n个数字,,要在这n个数字中找出a,b,c,d。。满足a,b,c,d是不同元素,并且a + b + c = d。。。求出最大的d

直接暴力时间复杂度为O(n^4)。。会超时。。所以需要一定技巧性的枚举

原式转换成a + b = d - c;

把n个数字从小到大排列。

由于d要求最大。所以从最大开始枚举。遇到符合条件就结束。

先枚举d和c。从最大开始枚举。。每次得到一个数d-c。。

然后枚举a和b。。a从最小开始 。。b从最大(由于元素不能相同。所以从c - 1)开始枚举。。

因为a往上找肯定比a大, b往下找肯定比a小。

如果a + b < d - c,a就往上找

反之。b就往下找。 直到满足条件就结束。。。

 #include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std; int main()
{
int a, b, c, d, n, ans, s[], flag;
while(scanf("%d", &n) != EOF && n)
{
for(int i = ; i < n; i++)
scanf("%d", &s[i]); flag = ;
sort(s, s+n);
for(d = n - ; d >= ; d--)
{
for(c = n - ; c > ; c--)
{
if(s[c] != s[d])
{
ans = s[d] - s[c];
}
for(a = , b = c-; a < b; )
{
if(ans == s[a] + s[b])
{
flag = ;
break;
}
else if(s[a] + s[b] < ans) a ++;
else b --;
}
if(flag) break;
}
if(flag) break;
}
if(flag) printf("%d\n", s[d]);
else printf("no solution\n");
} return ;
}

or:

 #include <cstdio>
#include <algorithm> using namespace std; int num[];
int ans, a, b, c, d, n, i; bool find()
{
for(a = n - ; a >= ; --a)
{
for (b = n - ; b > ; --b)
{
if(a == b) continue;
ans = num[a] - num[b];
for (c = , d = b - ; c < d; )
{
if(num[c] + num[d] == ans) return true;
else if( num[c] + num[d] < ans) ++c;
else --d;
}
}
}
return false;
} int main()
{
while(scanf("%d", &n), n)
{
for(i = ; i < n; ++i) scanf("%d", &num[i]);
sort(num, num + n);
if(find()) printf("%d\n", num[a]);
else puts("no solution");
}
}