Description
Input
Output
Sample Input
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 Output
5
Hint
这道题的题意为给你n行,每行4个数,要求你从这四列中每列选一个数使他们的和为0,求种类数目。
这道题普通的枚举绝对会超时,所以要用二分查找,并且先将前两列跟后两列分别求和,然后就转化为两个数组中找两个数使其他们的和为0的种类数了。
源代码如下:
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<stdio.h>
int m,a[4005][4],x[16000005]={0},y[16000005]={0};
using namespace std;
int main()
{ int max,min,mid,n,i,j,k=0,h=0;
scanf("%d",&n);
for(i=0;i<n;++i)
for(j=0;j<4;++j)
{ scanf("%d",&a[i][j]);
}
for(i=0;i<n;++i)
for(j=0;j<n;++j)
{ x[k]=a[i][0]+a[j][1];
y[k]=a[i][2]+a[j][3];
++k;
}
sort(x,x+k);
sort(y,y+k);
for(i=0;i<k;++i)
{
min=0;
max=k-1;
while(min<=max)
{ mid=(min+max)/2;
if(y[mid]+x[i]==0)
{ h++;
for(j=mid+1;j<k;++j)
{ if(y[j]+x[i]==0)h++;
else break;
}
for(j=mid-1;j>=0;--j)
{ if(y[j]+x[i]==0)h++;
else break;
}
break;
}
if(y[mid]+x[i]<0)
min=mid+1;
else max=mid-1;
}
}
printf("%d\n",h);
}
注意这种较大循环的输入输出要用scanf跟printf,用cin跟cout容易超时。