题目大意
给定一组整数,求最大的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;
}
就这样。