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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章