题目链接:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3593
题意:输入n*4的矩阵,从4列中每个选一个数求有多少个和为0;
1
6
-45 22 42 -16
-41 -27 56 30
-36 53 -37 77
-36 30 -75 -46
26 -38 -10 62
-32 -54 -6 45
Sample Explanation: Indeed, the sum of the five following quadruplets is zero: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46), (-32, 30, -75, 77), (-32, -54, 56, 30).
解析:暴力会超时。所以我们可以把前两列各个的和存下来,后两列的存下来。然后用二分查找即可。注意有重复和,所以找到一个符合条件的mid以后,要再mid前后各找一遍符合条件的和!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=4005*4005;
int a[maxn],b[maxn];
int m[4005][5];
int main()
{
int n;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=4;j++)
scanf("%d",&m[i][j]);
}
int tot=0;int tob=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
a[tot++]=m[i][1]+m[j][2];
b[tob++]=m[i][3]+m[j][4];
}
}
sort(b,b+tob);
// cout<<tot<<endl;
int ans=0;
for(int i=0;i<tot;i++)
{
int l=0,r=tot-1,mid;
while(l<=r)
{
mid=(l+r)/2;
if(a[i]+b[mid]>0)
{
r=mid-1;
}
else if(a[i]+b[mid]<0)
{
l=mid+1;
}
else
{
for(int j=mid;j<tot;j++)
{
if(a[i]==-b[j])
ans++;
else
break;
}
for(int j=mid-1;j>=0;j--)
{
if(a[i]==-b[j])
ans++;
else
break;
}
break;
}
}
}
cout<<ans<<endl;
if(t)
cout<<endl; //不清楚
}
}