题目描述:
>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); }