您的位置:首页 > 其它

UVA 10125 Sumsets .

2016-11-08 14:32 453 查看
题目地址:http://vjudge.net/problem/UVA-10125

一个集合中 ,三个不同的数加起来,等于集合中的另一个数

集合有n=1000个数

最简单的方法是枚举4数个,O(n*n*n*n)肯定不可能

试着把式子变一下型:a+b+c=d->a+b=d-c ,或者a+b=c-d,(a,b,c,d不是同一个数字)

#include <bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(int i=a;i<=(b);++i)
#define REPD(i,a,b) for(int i=a;i>=(b);--i)
const int maxn=1000+5;
int a[maxn],Pcnt=0,Mcnt=0;
struct Node
{
int p1,p2,val;
bool operator < (const Node& n) const{
return val<n.val;
}
bool operator == (const Node& n) {
return p1!=n.p1&&p1!=n.p2&&p2!=n.p1&&p2!=n.p2&&val==n.val;
}
}Plus[maxn*500],Minus[maxn*500*2];
int find(int x){
int L=1,R=Mcnt-1;
while(L<=R){
int mid=(L+R)>>1;
if(Minus[mid].val==x) return mid;
else if(Minus[mid].val<x) L=mid+1;
else R=mid-1;
}
return -1;
}
int solve(){
sort(Minus,Minus+Mcnt);
int ans=-1;
REP(i,0,Pcnt-1) {
int p=find(Plus[i].val);
if(p==-1) continue;
if(Plus[i]==Minus[p]) ans=max(ans,Minus[p].p1);
}
return ans;
}
int main(int argc, char const *argv[])
{
int n;
while(scanf("%d",&n)==1&&n){
REP(i,1,n) scanf("%d",&a[i]);
sort(a+1,a+1+n);
Pcnt=Mcnt=0;
REP(i,1,n) REP(j,i+1,n){
Plus[Pcnt++]=Node{i,j,a[i]+a[j]};
Minus[Mcnt++]=Node{i,j,a[i]-a[j]}; //d-c d要大,所以p1要大
Minus[Mcnt++]=Node{j,i,a[j]-a[i]};
}
int ans=solve();
if(ans==-1) printf("no solution\n");
else printf("%d\n", a[ans]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: