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>Constintn=4005;inta[4][n];struct hash_map{Static constintmask=0x7fffff;intp[mask+1],Q[mask+1]; void Clear () {memset (Q,0, sizeof (Q)); }int& operator [] (intK) {intI for(i=k&mask;Q[i]&&p[i]!=k;i= (i+1) &mask); P[i]=k;return Q[i]; }}; Hash_map Hash;intMain () {intT;SCANF ("%d", &t); for(intt=0; t<t;t++) {intN scanf"%d", &n); for(intj=0; j<n;j++) for(intI=0;i<4; i++) scanf ("%d", &a[i][j]); Hash.clear (); for(intI=0; i<n;i++) for(intj=0; j<n;j++) hash[a[0][i]+a[1][j]]++;intans=0; for(intI=0; i<n;i++) for(intj=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 intn=4005;inta[4][n];intSum[n*n];intMain () {intTscanf("%d", &t); for(intt=0; t<t;t++) {intNscanf("%d", &n); for(intj=0; j<n;j++) for(intI=0;i<4; i++)scanf("%d", &a[i][j]);intCnt=0; for(intI=0; i<n;i++) for(intj=0; j<n;j++) sum[cnt++]=a[0][i]+a[1][J];intans=0; Sort (sum,sum+cnt); for(intI=0; i<n;i++) for(intj=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;}
Uva 1152 and 4 values of 0 hash/two points