poj 2785 让和为0 暴力&二分85

针对POJ 2785问题,提出了一种通过组合两列数据并使用二分查找来优化求解四个数之和等于0的方法。该方法将原始的时间复杂度从O(n^4)降低到更高效的级别。

poj 2785 让和为0 暴力&二分

大意是输入一个n行四列的矩阵,每一列取一个数,就是四个数,求有多少种着四个数相加和为

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[4001],b[4001],c[4001],d[4001];
int ab[4000*4000+1],cd[4000*4000+1];
int k2;
int check(int x)
{
    int left=1,right=k2-1,mid;
    while (left<=right)
    {
        mid=(left+right)/2;
        if (x==cd[mid])
        {
            int w=0,e=mid;
            while (x==cd[e]&&e<k2)
                e++,w++;
            e=mid-1;
            while (x==cd[e]&&e>0)
                e--,w++;
            return w;
        }
        else if (x<cd[mid])
            right=mid-1;
        else
            left=mid+1;
    }
    return 0;
}
int main()
{
    int t,i,j,q;
    while (~scanf("%d",&t))
    {
        for (i=1;i<=t;i++)
            scanf("%d %d %d %d",&a[i],&b[i],&c[i],&d[i]);
        memset(ab,0,sizeof(ab));
        memset(cd,0,sizeof(cd));
        int k1=1,sum=0;
        k2=1;
        for (i=1;i<=t;i++)
        {
            for (j=1;j<=t;j++)
            {
                ab[k1++]=a[i]+b[j];
                cd[k2++]=-(c[i]+d[j]);
            }
        }
        sort(cd+1,cd+k2);
        for (i=1;i<k1;i++)
            sum+=check(ab[i]);
        printf("%d\n",sum);
    }
    return 0;
}

0的情况

首先脑海里想到的第一思维必然是一个个枚举,用四个for循环,那时间复杂度变成了On4,n的最大值是4000.

肯定会超时。那么,为了简化时间,首先我们可以开两个至少4000*4000的数组分别把第一列与第二列的和的情况

,第三列与第四列的和的情况存起来。这样就只用考虑两个数组的情况。

然后把两个数组排序,一个数组从头部开始同时另一个数组从尾部开始讨论和为0的情况(利用了递增性质和递减性质)

 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值