UVA 10125 Sumsets .

题目地址: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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值