UVA 10125 Sumsets .

来源:互联网 发布:大数据涂子沛概括 编辑:程序博客网 时间:2024/06/08 09:23

题目地址: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;}



0 0
原创粉丝点击