题目链接:http://poj.org/problem?id=2785
大意是输入一个n行四列的矩阵,每一列取一个数,就是四个数,求有多少种着四个数相加和为0的情况
首先脑海里想到的第一思维必然是一个个枚举,用四个for循环,那时间复杂度变成了On4,n的最大值是4000.
肯定会超时。那么,为了简化时间,首先我们可以开两个至少4000*4000的数组分别把第一列与第二列的和的情况
,第三列与第四列的和的情况存起来。这样就只用考虑两个数组的情况。
然后把两个数组排序,一个数组从头部开始同时另一个数组从尾部开始讨论和为0的情况(利用了递增性质和递减性质)
(PS:也可以二分,但代码不为二分)
#include<cstdio> #include<algorithm> using namespace std; int a[4001],b[4001],c[4001],d[4001]; int ab[4000*4000+1],cd[4000*4000+1]; int main() { int n,i,j,k,num,sum,x; while (~scanf("%d",&n)) { for (i=0;i<n;i++) scanf("%d %d %d %d",&a[i],&b[i],&c[i],&d[i]); k=0; for (i=0;i<n;i++){ for (j=0;j<n;j++) ab[k++]=a[i]+b[j]; } k=0; for (i=0;i<n;i++){ for (j=0;j<n;j++) cd[k++]=c[i]+d[j]; } sort(ab,ab+n*n); sort(cd,cd+n*n); x=n*n-1;sum=0; for (i=0;i<n*n;i++) { while (x>=0&&ab[i]+cd[x]>0) x--; if (x<0) break; num=x; while (ab[i]+cd[num]==0&&num>=0) { sum++; num--; } } printf("%d\n",sum); } return 0; }
时间: 2024-10-25 05:20:52