UVA 1152 4 Values whose Sum is 0 (hash)

题意:给你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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值