POJ 2549 Sumsets

题目

题目大意

给定一组整数,求最大的d,使得a + b + c = d,其中a、b、c和d是S的不同元素。

1 <= n <= 1000,表示以S为单位的元素数,后跟S元素,每行一个。

S的每个元素都是介于-536870912和+536870911之间的不同整数。

最后一行输入包含0。

对于每个S,一行包含d,或者一行包含“no solution”。

题目分析

先来他个暴搜。不不不,还是来他个正解吧。

我们先排序,然后假设a<b<c,因为a+b+c=d,所以a+b=d-c。

我们可以枚举c和d,然后找有没有符合条件的a+b就好啦。

因为a<b<c,所以a和b的位置一定在c前面对吧(即a和c的范围为第一个数~c前的数)。

我们令a等于第一个数,令b等于c前的数(要求a!=b且a<b)。

如果a+b<c,说明你的a太小啦。a往后挪一位。

如果a+b>c,说明你的b太大啦,b往前挪一位。

如果a+b=c,皆大欢喜,你找到了answer。

就是这么多,我的语文水平也就这样了。可以看看代码再捋顺一下思路。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

bool f;//f用来判断是否找到了answer 
int n,ans,s[1010];

int main()
{
	while(1)
	{
		scanf("%d",&n); if(n==0) break;
		for(int i=1;i<=n;i++) scanf("%d",&s[i]);
		f=false; sort(s+1,s+1+n);
		for(int i=n;i>=1;i--)//枚举d的位置 
		{
			int d=s[i];
			for(int j=n;j>=3;j--)//枚举c的位置,c前面必有a,b,所以最小的位置是3 
			{
				int c=s[j];
				if(i==j) continue;//题目规定a、b、c和d是S的不同元素 
				int pa=1,pb=j-1;//pa是a的位置,pb是b的位置
				while(pa<pb)
				{
					int a=s[pa],b=s[pb];
					if(a+b<d-c) pa++;//a往后挪一位
					else if(a+b>d-c) pb--;//b往前挪一位
					else if(a+b==d-c)
					{
						if(a!=d&&b!=d&&c!=d)//题目规定a、b、c和d是S的不同元素 
						{
							f=true;//标记找到answer了 
							ans=d;
						}
					}
					if(f) break;
				}
				if(f) break;
			}
			if(f) break;
		}
		if(!f) printf("no solution\n");
		else printf("%d\n",ans);
	}
	return 0;
}

就这样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值