算法核心:
使用键值对 map 实现对排列组合的快速查找。分两次求和,求和的结果sum作为索引放入map键值对中,键值对的值默认为0。所以每次找到sum,就让对应的键值对map[sum]++,
就可以记录下 求和结果为sum的排列组合可能有n个了。
详情可以参考下文:
P1748 a+b+c+d==0 - 辛夸高岭桂 - 博客园
题目描述:
求和问题可以被看做是以下的公式,给定 A,B,C,D 四个列表,计算有多少四元组满足 (a, b, c, d) ∈ A × B × C × D 且 a + b + c + d = 0。我们推测所有的列表都有 n 个数字。
注:不同的四元组是指元素位置不一样的四元组
数据范围 n<=2e3n<=2e3n<=2e3
样例输入
输入的第一个数字指明有 T 组。每一组这样描述,第一行是列表大小 n, 然后有 n 行。每一行都有四个整型数字,分别属于 A,B,C,D 四列。
样例输出
对于每一个测试用例,统计有多少个四元组满足他们的和是 0 。每一组数据一行。
Sample Input
Copy to Clipboard
1 6 -45 22 42 -16 -41 -27 56 30 -36 53 -37 77 -36 30 -75 -46 26 -38 -10 62 -32 -54 -6 45
Sample Output
Copy to Clipboard
5
代码如下:
#include<bits/stdc++.h>
using namespace std;
/*
*
1
6
-45 22 42 -16
-41 -27 56 30
-36 53 -37 77
-36 30 -75 -46
26 -38 -10 62
-32 -54 -6 45
*/
int main()
{
int n;
while (cin >> n)
{
for (int i = 0; i < n; i++)
{
int c;//数据的列数
while (cin >> c)
{
vector<int> A(c, 0);
vector<int> B(c, 0);
vector<int> C(c, 0);
vector<int> D(c, 0);
for (int i = 0; i < c; i++)
{
cin >> A[i] >> B[i] >> C[i] >> D[i];
}
// 初始化完毕--------
int count = 0;
int sum = 0;
/*使用MAP容器 或者一个两行n列的矩阵进行快速查找功能*/
map<int, int> mp;
for (int i = 0; i < c; i++)
{
for (int j = 0; j < c; j++)
{
mp[A[i] + B[j]]++;
}
}
for (int i = 0; i < c; i++)
{
for (int j = 0; j < c; j++)
{
if (mp[-(C[i] + D[j])]>0)
{
count+=mp[-(C[i] + D[j])];
}
}
}
cout << count << endl;
}
}
}
return 0;
}