题解 SP1296 【SUMFOUR - 4 values whose sum is 0】
这道题我们可以用4层循环做,复杂度
于是我们考虑优化,不难想到利用二分优化,我们可以进行两次二分。
第一次是思想上的,就是把
第二次是真正的二分,我们先用
前置知识:
lower_bound(a+1,a+n+1,b); 意思是在下角标为
upper_bound(a+1,a+n+1,b);找的是第一个大于b的数的地址,剩下的与lower_bound()都一样。
注意:上面的两个函数都是二分(
如果太懒不想写二分的话,可以用这两个函数代替(比如我qwq)
附代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 4010
using namespace std;
int a[N],b[N],c[N],d[N];
int sum1[N*N],sum2[N*N]; //预处理a+b和c+d,因为要二分,所以只能开一维数组
int len1,len2;
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
sum1[++len1]=a[i]+b[j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
sum2[++len2]=c[i]+d[j];
sort(sum1+1,sum1+len1+1);
sort(sum2+1,sum2+len2+1);
int ans=0;
for(int i=1;i<=len1;i++)
ans+=upper_bound(sum2+1,sum2+len2+1,-sum1[i])-lower_bound(sum2+1,sum2+len2+1,-sum1[i]); //因为可能有多个符合条件的组合,所以要这样写(自己理解一下)
printf("%d\n",ans);
return 0;
}