4 Values whose Sum is 0(二分)

题目链接:4 Values whose Sum is 0

啊啊啊,这一题真是亏了,应该二分交一发的,只怪那回lower_bound和upper_bound写出阴影了,导致这回都不敢交了(要好好学习一下了)。

题目大意:给你n组数,每组给出四个数,从每一列选出一个数,使得四个数的和为0,问有多少种组合方法。

思路:前两组任意组合,记录所有的情况存入sum1数组中,后两组也任意组合,记录所有的情况存入sum2数组中。将两组数都从小到大排列。遍历sum1中的数,用lower_bound和upper_bound在sum2数组中查找 “-sum1[i]”,求一下和即可。

这回我一定要记住了,不要在记混了,还要在学习一下,手写的查找上限和下限。

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=4009;
int a[maxn],b[maxn],c[maxn],d[maxn];

int sum1[maxn*maxn],sum2[maxn*maxn];

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=0; i<n; i++)
            scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);

        for(int i=0; i<n; i++)//前两个的组合
            for(int j=0; j<n; j++)
                sum1[i*n+j]=a[i]+b[j];

        for(int i=0; i<n; i++)//后两个的组合
            for(int j=0; j<n; j++)
                sum2[i*n+j]=c[i]+d[j];

        sort(sum1,sum1+n*n);
        sort(sum2,sum2+n*n);

        int ans=0;
        int f;
        for(int i=0; i<n*n; i++)
        {
            if(i-1>=0&&sum1[i]==sum1[i-1])//重复的不用再查了
                ans+=f;
            else
            {
                int s=lower_bound(sum2,sum2+n*n,-sum1[i])-sum2;//查下限
                int e=upper_bound(sum2,sum2+n*n,-sum1[i])-sum2;//查上限
                ans+=e-s;
                f=e-s;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章