原来比赛做过这种题
给四列数,要求每列中取一个,求四个数的和为0。
因为每列数的个数比较大,四次方太大,所以先合并成两列,
再从两列数中找和为0的,这里就可以先排个序,然后二分来找。
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define inf 0x3f3f3f3f
using 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;
}