10125 - Sumsets(*****)

/* 普通解法,超时! */ #include <cstdio> #include <algorithm> //using namespace std; int n,S[1010]; int search(int u) { bool ok=false; int left=0,right=n-1,mid; while(left<=right) { mid=(left+right)/2; if(u>S[mid]) left=mid+1; else if(u<S[mid]) right=mid-1; else { ok=true; break; } } if(ok) return mid; else if(left==n) return -2; else return -1; } int main() { //freopen("data.in","r",stdin); int count; while(scanf("%d",&n)==1) { if(n==0) break; count=0; for(int i=0;i<n;i++) scanf("%d",&S[i]); std::sort(S,S+n); int max=-1; for(int a=0;a<n;a++) for(int b=a+1;b<n;b++) for(int c=b+1;c<n;c++) { int k=search(S[a]+S[b]+S[c]); if(k>=0) { if(k>max) max=k; } else if(k==-2) break; } if(max!=-1) printf("%d\n",S[max]); else printf("no solution\n"); } return 0; }
/* 推荐题型:五星 题意:从数集中找出满足条件:d=a+b+c的所有情况,输出d可取的最大值 hash函数处理,使用数组head和next来实现。 */ #include <cstdio> #include <cstring> #include <algorithm> const int hMax=1000010,nMax=1010; int head[hMax],next[hMax]; int st[hMax][2]; long long a[nMax],sum[hMax]; int hash(long long u) { u=(((int)u<<1)+((int)u>>1))/2; return (u & 0x7fffffff)%hMax; } void insert(int k) { int h=hash(sum[k]); next[k]=head[h]; head[h]=k; } bool find(int x,int y,long long ans) { int h=hash(ans); for(int i=head[h];i!=-1;i=next[i]) if(sum[i]==ans && st[i][0]!=x && st[i][0]!=y && st[i][1]!=x && st[i][1]!=y) return true; return false; } int main() { //freopen("data.in","r",stdin); int n; while(scanf("%d",&n) && n) { memset(head,-1,sizeof(head)); for(int i=0;i<n;i++) scanf("%lld",&a[i]); std::sort(a,a+n); int k=0; for(int i=0;i<n;i++) for(int j=i+1;j<n;j++) { sum[k]=a[i]+a[j]; st[k][0]=i;st[k][1]=j; insert(k); k++; } int max=-1; for(int i=n-1;i>=0 && max==-1;i--) for(int j=0;j<n && max==-1;j++) if(i==j) continue; else { if(find(i,j,a[i]-a[j])) max=i; } if(max==-1) printf("no solution\n"); else printf("%lld\n",a[max]); } return 0; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值