PKU 2785 4 Values whose Sum is 0

4 Values whose Sum is 0
Time Limit: 15000MS
Memory Limit: 228000K
Total Submissions: 6014
Accepted: 1456
Case Time Limit: 5000MS

Description

The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute how many quadruplet (a, b, c, d ) ∈ A x B x C x D are such that a + b + c + d = 0 . In the following, we assume that all lists have the same size n .

Input

The first line of the input file contains the size of the lists n (this value can be as large as 4000). We then have n lines containing four integer values (with absolute value as large as 2 28 ) that belong respectively to A, B, C and D .

Output

For each input file, your program has to write the number quadruplets whose sum is zero.

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

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).

Source

Southwestern Europe 2005

偶用2分过了以后又用HASH过了次,发现HASH就是快- -!
2分5000MS+,HASH 3000MS+
差距啊。。。

2分就是先把1,2两列的和先算出来,然后再把3,4两列的和也算出来,最后二分查找得到一个解,注意解的附近也可能有解存在!

HASH的时候开静态数会很快~偶用的是最土的取MOD完接表。

下面是2分代码:
  1. //代码不长不过效率相对来说不怎么高...,复杂度2*N^2 *(logN + 1)
  2. #include<iostream>
  3. #include<algorithm>
  4. using namespace std;
  5. #define N 4000
  6. #define M 16000000
  7. int a[N],b[N],c[N],d[N],ab[M],cd[M];
  8. int main()
  9. {
  10.     int n,i,j,k,l,r,mid,cnt,ablen,cdlen;
  11.     while(scanf("%d",&n)!=EOF)
  12.     {
  13.     cnt=ablen=cdlen=0;
  14.     for(i=0;i<n;i++)
  15.     {
  16.         scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
  17.     }
  18.     for(i=0;i<n;i++)
  19.         for(j=0;j<n;j++)
  20.             ab[ablen++]=a[i]+b[j];
  21.     for(i=0;i<n;i++)
  22.         for(j=0;j<n;j++)
  23.             cd[cdlen++]=-c[i]-d[j];
  24.     sort(cd,cd+cdlen);
  25.     for(i=0;i<ablen;i++)
  26.     {
  27.         l=0;
  28.         r=cdlen-1;
  29.         while(l<=r)
  30.         {
  31.             mid=(l+r)/2;
  32.             if(cd[mid]==ab[i])
  33.             {
  34.                 cnt++;
  35.                 for(k=mid+1;k<cdlen;k++)
  36.                     if(cd[k]!=ab[i])break;
  37.                     else cnt++;
  38.                 for(k=mid-1;k>=0;k--)
  39.                     if(cd[k]!=ab[i])break;
  40.                     else cnt++;
  41.                 break;
  42.             }
  43.             if(cd[mid]<ab[i])
  44.                 l=mid+1;
  45.             else r=mid-1;
  46.         }
  47.     }
  48.     printf("%d/n",cnt);
  49.     }
  50.     return 0;
  51. }

之后的HASH写的就比较顺利,有了ZX大牛的指点,1次AC,效率比他还高- -!!


  1. #include<iostream>
  2. using namespace std;
  3. #define N 4000
  4. #define M 17100000
  5. const int p=1048576;//(1<<20) 为了取MOD的时候效率高点~
  6. struct Node
  7. {
  8.     int val,cnt,next;
  9. };
  10. Node hash[M];
  11. bool flag[M];
  12. int a[N][4],hlen=p,cnt=0;
  13. inline int gn()
  14. {
  15.     char buf=getchar();
  16.     int sgn=(buf=='-'?-1:1),ret=0;
  17.     if(buf!='-')ungetc(buf,stdin);
  18.     while((buf=getchar())!=' '&&buf!='/n')
  19.         ret=ret*10+(buf-48);
  20.     return ret*sgn;
  21. }
  22. void ins(int val,int key)
  23. {
  24.     if(!flag[key])
  25.     {
  26.         flag[key]=true;
  27.         hash[key].cnt=1;
  28.         hash[key].val=val;
  29.         hash[key].next=-1;
  30.         return;
  31.     }
  32.     while(key!=-1)
  33.     {
  34.         if(val==hash[key].val)
  35.         {
  36.             hash[key].cnt++;
  37.             return;
  38.         }
  39.         if(hash[key].next==-1)break;
  40.         key=hash[key].next;
  41.     }
  42.     hash[key].next=++hlen;
  43.     hash[hlen].val=val;
  44.     hash[hlen].cnt=1;
  45.     hash[hlen].next=-1;
  46. }
  47. void fnd(int val,int key)
  48. {
  49.     if(!flag[key])
  50.         return;
  51.     while(key!=-1)
  52.     {
  53.         if(val==hash[key].val)
  54.         {
  55.             cnt+=hash[key].cnt;
  56.             return;
  57.         }
  58.         key=hash[key].next;
  59.     }
  60. }
  61. int main()
  62. {
  63.     int n,i,j,tmp;
  64.     bool nag;
  65.     n=gn();
  66.     for(i=0;i<n;i++)
  67.         for(j=0;j<4;j++)
  68.             a[i][j]=gn();
  69.     for(i=0;i<n;i++)
  70.         for(j=0;j<n;j++)
  71.         {
  72.             tmp=a[i][0]+a[j][1];
  73.             nag=tmp<0;
  74.             if(nag)tmp*=-1;
  75.             ins(a[i][0]+a[j][1],tmp&(p-1));
  76.         }
  77.     for(i=0;i<n;i++)
  78.         for(j=0;j<n;j++)
  79.         {
  80.             tmp=-a[i][2]-a[j][3];
  81.             nag=tmp<0;
  82.             if(nag)tmp*=-1;
  83.             fnd(-a[i][2]-a[j][3],tmp&(p-1));
  84.         }
  85.     printf("%d/n",cnt);
  86.     return 0;
  87. }

你可能感兴趣的:(File,Integer,ini,input,each,output)