给出四组数a[],b[],c[],d[],求x1+x2+x3+x4=0的方案数。其中x1属于a,x2属于b....
这几天学Linux学累了,找几道算法题做做,毕竟很长时间没写acm程序了,手都生了。起初自己的想法便是将a和b的组合方案数存入一数组中并进行排序,然后枚举c和d构成的方案在相应的数组中查找出现的次数将结果累加到最终结果中。其中自己采用了两种方法来做的<1>二分<2>散列表(注意hash数组开的要大一些,否则在一些方案数太多的时候会TLE,这是程序本身的原因)。做完这题发现acm这东西不能放,得一直练着,好吧,以后争取每天做两道题来保持思维。。。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define inf 0x3f3f3f3f
//#define sponge_wxy_code
using namespace std;
/*
const int maxn = 4010;
int a[maxn], b[maxn], c[maxn], d[maxn], arr[maxn*maxn];
int len;
int ans;
*/
const int maxn = 4010;
const int table_size = 10000007;
int a[maxn], b[maxn], c[maxn], d[maxn];
int hash[table_size], mark[table_size], value[table_size];
int ans;
void init_hash() {
memset(hash, 0, sizeof(hash));
memset(mark, -1, sizeof(mark));
memset(value, inf, sizeof(value));
}
int get_key(int val) {
return (val % table_size + table_size) % table_size;
}
void insert_hash(int val) {
int pos = get_key(val);
if(mark[pos] == -1) {
mark[pos] = 1;
hash[pos] = 1;
value[pos] = val;
return ;
} else if(value[pos] == val) {
hash[pos]++;
return ;
}
while((value[pos] != val) && mark[pos] != -1) {
pos = (pos + 1) % table_size;
}
if(mark[pos] == -1) {
mark[pos] = 1;
hash[pos] = 1;
value[pos] = val;
}
else {
hash[pos]++;
}
return ;
}
int find_hash(int val) {
int pos = get_key(val);
if(mark[pos] == -1) return 0;
while((value[pos] != val) && mark[pos] != -1) {
pos = (pos + 1) % table_size;
}
if(mark[pos] == -1) return 0;
return hash[pos];
}
/*
int binary_search_one(int val) {
int l = 0, r = len - 1;
int pos = inf;
while(l <= r) {
int mid = (l + r) >> 1;
if(arr[mid] < val) {
l = mid + 1;
} else {
r = mid - 1;
if(arr[mid] == val) {
pos = min(pos, mid);
}
}
}
if(pos == inf) return -1;
return pos;
}
int binary_search_two(int val) {
int l = 0, r = len - 1;
int pos = -inf;
while(l <= r) {
int mid = (l + r) >> 1;
if(arr[mid] > val) {
r = mid - 1;
} else {
l = mid + 1;
if(arr[mid] == val) {
pos = max(pos, mid);
}
}
}
if(pos == -inf) return -1;
return pos;
}
*/
int main() {
#ifdef sponge_wxy_code
freopen("aa.in", "r", stdin);
freopen("bb.out", "w", stdout);
#endif
int n;
//int T, n, kcase = 0;
//scanf("%d", &T);
while(scanf("%d", &n) != EOF) {
//if(kcase) puts("");
//kcase++, ans = 0;
//scanf("%d", &n);
ans = 0;
init_hash();
for(int i = 0; i < n; ++i) scanf("%d %d %d %d", &a[i], &b[i], &c[i], &d[i]);
/*
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
arr[len++] = a[i] + b[j];
}
}
*/
//printf("Length:%d\n", len);
/*
sort(arr, arr + len);
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
int temp = -(c[i] + d[j]);
int pos1 = binary_search_one(temp);
if(pos1 == -1) continue;
int pos2 = binary_search_two(temp);
ans += (pos2 - pos1 + 1);
//printf("%d %d %d\n", temp, pos1, pos2);
//ans += (upper_bound(arr, arr + len, temp) - lower_bound(arr, arr + len, temp));
}
}
*/
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
insert_hash(a[i] + b[j]);
}
}
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
int temp = -(c[i] + d[j]);
ans += find_hash(temp);
}
}
printf("%d\n", ans);
}
return 0;
}