题意:给你4组数 每组数都含有相同个数的元素 分别从每组数中选一个数 问你有多少种方案使得它们的和为零
思路:枚举前两组数的所有和 并将它们存入哈希表中 然后再枚举后两组数的所有和 判断是否在哈希表中存在
#include <cstdio>
using namespace std;
#define REP( i, a, b ) for( int i = a; i < b; i++ )
const int maxn = 4000 + 10;
const int MOD = 10000007;
struct HashTable{
int va, cnt;
HashTable *next;
HashTable(int va = 0, int cnt = 0) : va(va), cnt(cnt) { next = NULL; }
} *Hashtable[MOD];
int n, cas = 0;
int a[maxn], b[maxn], c[maxn], d[maxn];
void Insert(int val){
int va = val > 0 ? val : -val;
int key = va % MOD;
HashTable *tmp = Hashtable[key];
while(tmp){
if(tmp -> va == val){
tmp -> cnt ++;
return;
}
tmp = tmp -> next;
}
tmp = new HashTable(val, 1);
tmp -> next = Hashtable[key];
Hashtable[key] = tmp;
}
int Find(int val){
int va = val > 0 ? val : -val;
int key = va % MOD;
if(Hashtable[key]){
HashTable *tmp = Hashtable[key];
while(tmp){
if(tmp -> va == val) return tmp -> cnt;
tmp = tmp -> next;
}
}
return 0;
}
void solve(){
int ans = 0;
REP(i, 0, MOD) Hashtable[i] = NULL;
scanf("%d", &n);
REP(i, 0, n) scanf("%d%d%d%d", &a[i], &b[i], &c[i], &d[i]);
REP(i, 0, n) REP(j, 0, n) Insert(a[i] + b[j]);
REP(i, 0, n) REP(j, 0, n) ans += Find(-c[i] - d[j]);
if(cas++) printf("\n");
printf("%d\n",ans);
}
int main()
{
//freopen("in.txt", "r", stdin);
int T;
scanf("%d", &T);
while(T--) solve();
return 0;
}