题意:给你一个含有n(n<=1000)个数的数列,问这个数列中是否存在四个不同的数a,b,c,d,使a+b+c=d;若存在则输出最大的d
思路:子集最多有1000C4*4个,时限只有一秒。折半枚举有些讲究,以前折半都是在集合上折半,这次是在等式上。将等式变化为 a + b = d – c,预先算好左右两边并排序。左边全枚举N2,右边二分查找logN2,每枚举一次左边都会在右边二分常数次,所以总的复杂度是O(N2logN2):
AC代码:
#include<stdio.h> #include<algorithm> using namespace std; const int MAX = 1000005; struct no { int s; int x; int y; bool operator < (const no& b)const { return s <b.s; } }m1[MAX],m2[MAX]; bool cmp(no a,no b) { return a.s<b.s; } bool pd(no a,no b) { return a.x != b.x && a.y != b.y && a.x != b.y && a.y != b.x; } int a[2000]; int main( ) { int n ; while(scanf("%d",&n)!=EOF) { int ans=-536870912; if(n==0) break; for(int i=0 ; i<n ; i++) scanf("%d",&a[i]); sort(a,a+n); int k=0; for(int i=0 ; i<n ; i++) for(int j=i+1 ; j<n ; j++) { m1[k].s=a[i]+a[j]; m1[k].x=i; m1[k].y=j; k++; } int l=0; for(int i=0 ; i<n ; i++) for(int j=i+1 ; j<n ; j++) { m2[l].s=a[i]-a[j]; m2[l].x=i; m2[l].y=j; l++; m2[l].s=a[j]-a[i]; m2[l].x=j; m2[l].y=i; l++; } sort(m1,m1+k); for(int i=0 ; i<l ; i++) { int d=lower_bound(m1,m1+k,m2[i])-m1; if(pd(m1[d],m2[i])&&m1[d].s==m2[i].s) ans=max(ans,m1[d].s+a[m2[i].y]); } if(ans!=-536870912) printf("%d ",ans); else printf("no solution "); } return 0; }
最后进行补充,,,,,这次道题用二分函数进行查找,如果是对结构体的话,要在结构体里面进行重载运算符