POJ2785 和为0的组合数(数的哈希)
来源:互联网 发布:软件缺陷报告模板 编辑:程序博客网 时间:2024/05/17 19:20
给定4个组合A,B,C,D,这四个组合里面的元素数目相等。要求找出所有的序列(a, b, c, d),四个数分别来自A,B,C,D四个组合,使得a + b + c + d = 0,输出这样的序列的总数。若两个满足条件的序列是完全相同的,它们也算是不同的序列,因为A,B,C,D中可能含有相同的元素。
解题思路很简单,取所有的(a, b)序列进行哈希,以a+b作为键,分别映射到非负数和负数两个哈希表上,若有重复的(a, b),则只需要记录次数,不需要再开辟结点存储。
然后对所有的(c, d)序列,以c+d作为键进行查找,若c+d为正则查找对应的负数哈希表,若为负则查找对应的非负数哈希表,把符合a+b+c+d=0的所有结点的所有次数相加就得到最后的答案了。
#include <iostream>#include <cstdio>#include <algorithm>using namespace std;const int N = 9000005;const int M = 4005;const int H = 4000007;int n;long long ans;int A[M], B[M], C[M], D[M];struct Node{int a;int b;int cnt;int next;};Node nodeP[N];Node nodeN[N];int curP, curN;int hashTableP[H];int hashTableN[H];void initHash(){for (int i = 0; i < H; ++i) hashTableP[i] = hashTableN[i] = -1;curP = curN = 0;ans = 0;}void searchHash(int& a, int& b){int h = (a + b) % H;int next;if (h >= 0) {next = hashTableP[h];while (next != -1){if (a == nodeP[next].a && b == nodeP[next].b) {++nodeP[next].cnt;return;}next = nodeP[next].next;}nodeP[curP].a = a;nodeP[curP].b = b;nodeP[curP].cnt = 1;nodeP[curP].next = hashTableP[h];hashTableP[h] = curP;++curP;}else{h = -h;next = hashTableN[h];while (next != -1){if (a == nodeN[next].a && b == nodeN[next].b) {++nodeN[next].cnt;return;}next = nodeN[next].next;}nodeN[curN].a = a;nodeN[curN].b = b;nodeN[curN].cnt = 1;nodeN[curN].next = hashTableN[h];hashTableN[h] = curN;++curN;}}void getAns(int& c, int& d){int h = (c + d) % H;int next;if (h > 0){next = hashTableN[h];while (next != -1){if (nodeN[next].a + nodeN[next].b + c + d == 0) ans += nodeN[next].cnt;next = nodeN[next].next;}}else{h = -h;next = hashTableP[h];while (next != -1){if (nodeP[next].a + nodeP[next].b + c + d == 0) ans += nodeP[next].cnt;next = nodeP[next].next;}}}int main(){initHash();scanf("%d", &n);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){searchHash(A[i], B[j]);}}for (int i = 0; i < n; ++i){for (int j = 0; j < n; ++j){getAns(C[i], D[j]);}}printf("%lld\n", ans);return 0;}
- POJ2785 和为0的组合数(数的哈希)
- 和为指定数的组合个数
- 组合数的和
- 三数之和为0的组合
- 二分贪心练习题--D(四个数和为0的组合数)
- 数组和两个数的和为20的组合
- 组合数和排列数的关系
- 立方数和的组合
- 1056. 组合数的和
- 1056. 组合数的和
- 1056. 组合数的和
- 1056. 组合数的和
- PAT1056 组合数的和
- 用1 2 5三个数不同个数的组合的和为100的组合
- 用1、2、5这三个数不同个数组合的和为100的组合数
- 求一个数组中三个数和为0的组合
- 组合数的输出
- 组合数的奇偶性
- c语言杂记
- FTP命令大全
- Hibernate_1+N问题
- BMP格式解析
- 字符串转为整数,不考虑进制
- POJ2785 和为0的组合数(数的哈希)
- altium designer 画箭头
- SQL JOIN TEST
- hdu 1247 字典树 Hat’s Words
- java-基础加强之枚举
- 【Android Training - 05】与其他Apps进行交互 [ Lesson 1 - 启动到另外一个app ]
- 硬盘方式安装redhat7
- Anger Begins&&http://acm.nbut.cn:8081/Contest/view/id/29/problem/A.xhtml
- 走出浮躁的泥沼:关于技术与工作