UVA 10125 Sumsets 技巧性的枚举

Problem C - Sumsets

Given S, a set of integers, find the largest d such that a + b + c = d where a, b, c, and d are distinct elements of S.

Input

Several S, each consisting of a line containing an integer 1 <= n <= 1000 indicating the number of elements in S, followed by the elements of S, one per line. Each element of S is a distinct integer between -536870912 and +536870911 inclusive. The last line of input contains 0.

Output

For each S, a single line containing d, or a single line containing "no solution".

Sample Input

5
2 
3 
5 
7 
12
5
2 
16 
64 
256 
1024
0

Output for Sample Input

12
no solution

题意:输入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 <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int n;
int num[1005];
int ans;
int a, b, c, d;
int main()
{
    while (scanf("%d", &n) != EOF && n)
    {
	int judge = 0;
	for (int i = 0; i < n; i ++)
	    scanf("%d", &num[i]);
	sort(num, num + n);
	for (d = n - 1; d >= 0; d --)
	{
	    for (a = n - 1; a > 1; a --)
	    {
		if (a != d)
		    ans = num[d] - num[a];
		for (b = 0, c = a - 1; b < c;)
		{
		    if (num[b] + num[c] == ans)
		    {
			judge = 1;
			break;
		    }
		    else if (num[b] + num[c] < ans)
			b ++;
		    else
			c --;
		}
		if (judge)
		    break;
	    }
	    if (judge)
		break;
	}
	if(judge)
	    printf("%d\n", num[d]);
	else
	    printf("no solution\n");
    }
    return 0;
}


你可能感兴趣的:(UVA 10125 Sumsets 技巧性的枚举)