题目描述:

>SUM问题可以表示为:给定四个具有整数值的列表A,B,C,D。
计算多少个四元组(a,b,c,d)∈A x B x C x D使得a + b + c + d = 0。在下文中,我们假定所有列表的大小均相同。

输入描述:

>输入文件的第一行包含列表n的大小(该值可以最大为4000)。然后,我们有n行包含四个分别属于A,B,C和D的整数值(绝对值最大为2 28)。

输出描述:

>对于每个输入文件,您的程序必须使四个数的总和为零。

题解

暴力即优雅
拿到这道题,首先想的就是4重for循环跑起来,一看数据范围,肯定要超时!
那我们优化一下?跑一个3重for循环然后去第四列找能不能有让他们和为0的数,本题数据范围为4000,一般情况我们认为1秒可以跑1e8,然后我们发现也会超时
那能不能再优化一下呢?我们可以跑两重for循环,把a数组和b数组所有情况全部算出来,c数组和d数组所有和的情况全部算出来,然后扫一遍数组匹配就好啦,复杂度,完美不超时。
POJ不能用万能头噢嘤嘤嘤

完整代码

#include<algorithm>
#include<cstdio>
#include<vector>
using namespace std;
#define ll long long
ll a[4050],b[4050],c[4050],d[4050];
vector<ll> sum1,sum2;
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%lld%lld%lld%lld",&a[i],&b[i],&c[i],&d[i]);
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            sum1.push_back(a[i]+b[j]);
            sum2.push_back(c[i]+d[j]);
        }
    }
    sort(sum2.begin(),sum2.end());
    ll ans=0;
    for(int i=0,len=sum1.size();i<len;++i){
        ans+=upper_bound(sum2.begin(),sum2.end(),-sum1[i])-lower_bound(sum2.begin(),sum2.end(),-sum1[i]);
    }
    printf("%lld\n",ans);
}