Test instructions
Given the set of 4 N (1 <= n <= 4000) elements A, B, C, D, it is required to select an element a, B, C, D, respectively, so that a+b+c+d = 0, ask how many kinds of selection method.
Analysis:
Obviously the four-heavy cycle is not enough, I first thought is to use a map to save A+b,c+d, and then in the search statistics. Timeout....
And then the book said with a hash table to achieve, see some of the hash of the puzzle is too ingenious, learn a bit.
There is the problem can be solved with two points, first calculate the A+b, and then enumerate C+d, and then two points to find the scope.
Hash 630ms:
#include <cstdio> #include <cstring> const int n=4005; int a[4][n]; struct HASH_MAP
{static const int mask=0x7fffff;
int p[mask+1],q[mask+1];
void Clear () {memset (q,0,sizeof (q));
} int& operator [] (int k) {int i;
For (i=k&mask;q[i]&&p[i]!=k;i= (i+1) &mask);
P[i]=k;
return q[i];
}
};
Hash_map Hash;
int main () {int t;scanf ("%d", &t);
for (int t=0;t<t;t++) {int n;
scanf ("%d", &n);
for (int j=0;j<n;j++) for (int i=0;i<4;i++) scanf ("%d", &a[i][j]);
Hash.clear ();
for (int i=0;i<n;i++) for (int j=0;j<n;j++) hash[a[0][i]+a[1][j]]++;
int ans=0;
for (int. i=0;i<n;i++) for (int j=0;j<n;j++) ANS+=HASH[-A[2][I]-A[3][J];
if (t) printf ("\ n");
printf ("%d\n", ans);
} return 0; }
Two points, 2720ms:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int n=4005;
int a[4][n];
int sum[n*n];
int main ()
{
int t;scanf ("%d", &t);
for (int t=0;t<t;t++) {
int n;
scanf ("%d", &n);
for (int j=0;j<n;j++)
for (int i=0;i<4;i++) scanf ("%d", &a[i][j]);
int cnt=0;
for (int. i=0;i<n;i++) for
(int j=0;j<n;j++)
sum[cnt++]=a[0][i]+a[1][j];
int ans=0;
Sort (sum,sum+cnt);
for (int i=0;i<n;i++) for
(int j=0;j<n;j++)
ans+=upper_bound (Sum,sum+cnt,-a[2][i]-a[3][j])-lower_ Bound (Sum,sum+cnt,-a[2][i]-a[3][j]);
if (t) printf ("\ n");
printf ("%d\n", ans);
}
return 0;
}