POJ 2785 4 Values whose Sum is 0

第一列和第二列的所有和处理出来,排序。

第三列和第四列的所有和处理出来,从上面处理出来的数组中二分得到答案。

用map被卡了。。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;

const int maxn=4000+10;
int n,tot;
long long a[maxn][6];
long long Q[20000000];
long long P[20000000];
struct X
{
    long long val;
    long long num;
}s[20000000];

long long work(long long tag)
{
    int l=0,r=tot;
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(s[mid].val<tag) l=mid+1;
        else if(s[mid].val==tag) return s[mid].num;
        else r=mid-1;
    }
    return 0;
}

int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=1; i<=n; i++)
            for(int j=1; j<=4; j++)
                scanf("%lld",&a[i][j]);

        int cnt=0;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                Q[cnt++]=a[i][1]+a[j][2];
        sort(Q,Q+cnt);

        tot=0;
        s[0].val=Q[0]; s[0].num=1;
        for(int i=1;i<cnt;i++)
        {
            if(Q[i]==Q[i-1]) s[tot].num++;
            else
            {
                tot++;
                s[tot].num=1;
                s[tot].val=Q[i];
            }
        }
        cnt=0;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                P[cnt++]=a[i][3]+a[j][4];

        long long ans=0;
        for(int i=0;i<cnt;i++) ans=ans+work(-P[i]);
        printf("%lld\n",ans);
    }
    return 0;
}

 

posted @ 2016-04-15 19:46  Fighting_Heart  阅读(149)  评论(0编辑  收藏  举报