poj 2785 4 Values Whose Sum is 0 --- 二分

来源:互联网 发布:飞天侠淘宝客9.0 编辑:程序博客网 时间:2024/05/22 10:28

原来比赛做过这种题

给四列数,要求每列中取一个,求四个数的和为0。

因为每列数的个数比较大,四次方太大,所以先合并成两列,

再从两列数中找和为0的,这里就可以先排个序,然后二分来找。



#include <iostream>#include <cstring>#include <string>#include <cstdio>#include <cmath>#include <algorithm>#include <vector>#include <queue>#include <map>#define inf 0x3f3f3f3fusing namespace std;int a[4010],b[4010],c[4010],d[4010],s1[16000010],s2[16000010];int main(){    int tmp,i,j,p1,p2,n,ans,bot,mid,top;    while(~scanf("%d",&n))    {        for(i=0;i<n;i++)        {            scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);        }        p1=p2=0;        for(i=0;i<n;i++)        {            for(j=0;j<n;j++)            {                s1[p1++]=a[i]+b[j];                s2[p2++]=-1*(c[i]+d[j]);            }        }        sort(s2,s2+p2);        ans=0;        for(i=0;i<p1;i++)        {            bot=0;top=p2-1;            while(bot<=top)            {                mid=(bot+top)/2;                if(s1[i]==s2[mid])                {                    ans++;                    tmp=mid+1;                    while(s1[i]==s2[tmp]&&tmp<p2)                    {                        ans++;                        tmp++;                    }                    tmp=mid-1;                    while(s1[i]==s2[tmp]&&tmp>=0)                    {                        ans++;                        tmp--;                    }                    break;                }                else                {                    if(s1[i]<s2[mid]) top=mid-1;                    else bot=mid+1;                }            }        }        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击