题目链接:http://poj.org/problem?id=2785

大意是输入一个n行四列的矩阵,每一列取一个数,就是四个数,求有多少种着四个数相加和为0的情况

首先脑海里想到的第一思维必然是一个个枚举,用四个for循环,那时间复杂度变成了On4,n的最大值是4000.

肯定会超时。那么,为了简化时间,首先我们可以开两个至少4000*4000的数组分别把第一列与第二列的和的情况

,第三列与第四列的和的情况存起来。这样就只用考虑两个数组的情况。

然后把两个数组排序,一个数组从头部开始同时另一个数组从尾部开始讨论和为0的情况(利用了递增性质和递减性质)

 

 

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 int a[4001],b[4001],c[4001],d[4001];
 5 int ab[4000*4000+1],cd[4000*4000+1];
 6 int main()
 7 {
 8     int n,i,j,k,num,sum,x;
 9     while (~scanf("%d",&n))
10     {
11         for (i=0;i<n;i++)
12             scanf("%d %d %d %d",&a[i],&b[i],&c[i],&d[i]);
13         k=0;
14         for (i=0;i<n;i++){
15             for (j=0;j<n;j++)
16                ab[k++]=a[i]+b[j];
17         }
18         k=0;
19         for (i=0;i<n;i++){
20             for (j=0;j<n;j++)
21                cd[k++]=c[i]+d[j];
22         }
23         sort(ab,ab+n*n);
24         sort(cd,cd+n*n);
25         x=n*n-1;sum=0;
26         for (i=0;i<n*n;i++)
27         {
28             while (x>=0&&ab[i]+cd[x]>0)
29                 x--;
30             if (x<0)
31                 break;
32             num=x;
33             while (ab[i]+cd[num]==0&&num>=0)
34             {
35                 sum++;
36                 num--;
37             }
38         }
39         printf("%d\n",sum);
40     }
41     return 0;
42 }

 

二分也很简单,找到相等个数就行

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int a[4001],b[4001],c[4001],d[4001];
 6 int ab[4000*4000+1],cd[4000*4000+1];
 7 int k2;
 8 int check(int x)
 9 {
10     int left=1,right=k2-1,mid;
11     while (left<=right)
12     {
13         mid=(left+right)/2;
14         if (x==cd[mid])
15         {
16             int w=0,e=mid;
17             while (x==cd[e]&&e<k2)
18                 e++,w++;
19             e=mid-1;
20             while (x==cd[e]&&e>0)
21                 e--,w++;
22             return w;
23         }
24         else if (x<cd[mid])
25             right=mid-1;
26         else
27             left=mid+1;
28     }
29     return 0;
30 }
31 int main()
32 {
33     int t,i,j,q;
34     while (~scanf("%d",&t))
35     {
36         for (i=1;i<=t;i++)
37             scanf("%d %d %d %d",&a[i],&b[i],&c[i],&d[i]);
38         memset(ab,0,sizeof(ab));
39         memset(cd,0,sizeof(cd));
40         int k1=1,sum=0;
41         k2=1;
42         for (i=1;i<=t;i++)
43         {
44             for (j=1;j<=t;j++)
45             {
46                 ab[k1++]=a[i]+b[j];
47                 cd[k2++]=-(c[i]+d[j]);
48             }
49         }
50         sort(cd+1,cd+k2);
51         for (i=1;i<k1;i++)
52             sum+=check(ab[i]);
53         printf("%d\n",sum);
54     }
55     return 0;
56 }

 

posted on 2015-07-21 10:24  蜘蛛侦探  阅读(1694)  评论(0编辑  收藏  举报