4 Values whose Sum is 0

4 Values whose Sum is 0

如果直接暴力枚举的话,其复杂度为\(O(n^4)\),这是必然超时的。

但是如果把这四个序列分成两半,通过遍历一半,而到另外一半去进行二分查找的话,复杂度就可以降为\(O(n^2log(n))\)

// Created by CAD on 2020/2/2.
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn=4005;
int a[maxn],b[maxn],c[maxn],d[maxn],s1[maxn*maxn],s2[maxn*maxn];
int main()
{
    int n;  cin>>n;
    for(int i=1;i<=n;++i)
        scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
    int cnt=0;
    for(register int i=1;i<=n;++i)
        for(register int j=1;j<=n;++j)
            s1[++cnt]=a[i]+b[j],s2[cnt]=c[i]+d[j];
    sort(s2+1,s2+1+cnt);
    int ans=0;
    for(register int i=1;i<=cnt;++i)
        ans+=upper_bound(s2+1,s2+1+cnt,-s1[i])-lower_bound(s2+1,s2+1+cnt,-s1[i]);
    printf("%d\n",ans);
    return 0;
}

同时又想到可以用 map 来进行查值,复杂度与二分相同,但是由于常数过大超时了,所以用unordered_map进行优化,它是用哈希表进行存值的,平均查找复杂度为\(O(1)\),但是由于 POJ 没有unordered_map这个头文件,所以提交不了。

// Created by CAD on 2020/2/2.
#include <iostream>
#include <cstdio>
#include <unordered_map>
using namespace std;
const int maxn=4005;
int a[maxn],b[maxn],c[maxn],d[maxn],s[maxn*maxn];
unordered_map<int,int> m;
int main()
{
    m.clear();
    int n;  cin>>n;
    for(int i=1;i<=n;++i)
        scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
    int cnt=0;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
            s[++cnt]=a[i]+b[j],m[c[i]+d[j]]++;
    int ans=0;
    for(int i=1;i<=cnt;++i)
        ans+=m[-s[i]];
    printf("%d\n",ans);
    return 0;
}
posted @ 2020-02-02 19:03  caoanda  阅读(144)  评论(0编辑  收藏  举报