题目描述
Farmer John 的奶牛正在 mooZ 视频会议平台上举行每日集会。她们发明了一个简单的数字游戏,为会议增添一些乐趣。
Elsie 有三个正整数 A、B 和 C,(1≤A≤B≤C)。这些数字是保密的,她不会直接透露给她的姐妹 Bessie。她告诉 Bessie N(4≤N≤7)个不同的整数 x1,x2...xn,并宣称每一个xi都是 A、B、C、A+B,B+C、C+A 或 A+B+C 之一。然而,Elsie 可能在撒谎;这些整数xi可能并没有对应任何一组合法的 (A,B,C)。Bessie 百思不得其解,所以需要靠你来求出与 Elsie 给出的数相符合的三元组 (A,B,C) 的数量。
每个输入包含 T(1≤T≤100)组需要独立求解的测试用例。
输入格式
输入的第一行包含 T。
每个测试用例的第一行包含 N,为 Elsie 给 Bessie 的整数的数量。
每个测试用例的第二行包含 N 个不同的整数 1,2,…,x1,x2,…,xN。
输出格式
对于每个测试用例,输出与 Elsie 给出的数相符合的三元组 (A,B,C) 的数量。
输入输出样例
题目解析
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
//T:题目规定的总输入组数
//n:每组数的个数
//x[8]:用来表示给定数组,长度为4-7,多预留一位
//sum:当前有多少种组合
//a,b,c:表示A,B,C
//d[8]:根据大小关系表示给定数组的组合情况:A,B,C,A+B,A+C,B+C,A+B+C
int T, n, x[8], sum, a, b, c, d[8];
//用于检查是否有重复的三元组
int ax[1000005], bx[1000005], cx[1000005];
void dfs(int t) //t表示当前的位置,如果当前位置 t 超过数组 x 的长度,即已经考虑完所有的数字
{
if (t > n)
{
//cout << "beging search" << endl;
a = d[1], b = d[2], c = d[3];
if (!d[4] && !d[5] && !d[6])
{
if (a + b + c == d[7] && a <= b && b <= c)sum++;
return;
}
if (d[4])//已知A+B
{
if (a && !b && d[4] - a <= 0)return;
else if (a && !b)b = d[4] - a;
if (!a && b && d[4] - b <= 0)return;
else if (!a && b)a = d[4] - b;
if (a && b && a + b != d[4])return;
if (d[7] && !c && d[7] - d[4] <= 0)return;
else if (d[7] && !c)c = d[7] - d[4];
if (d[7] && c && d[7] - c != d[4])return;
}
if (d[5])
{
if (b && !c && d[5] - b <= 0)return;
else if (b && !c)c = d[5] - b;
if (!b && c && d[5] - c <= 0)return;
else if (!b && c)b = d[5] - c;
if (b && c && b + c != d[5])return;
if (d[7] && !a && d[7] - d[5] <= 0)return;
else if (d[7] && !a)a = d[7] - d[5];
if (d[7] && a && d[7] - a != d[5])return;
}
if (d[6])
{
if (a && !c && d[6] - a <= 0)return;
else if (a && !c)c = d[6] - a;
if (!a && c && d[6] - c <= 0)return;
else if (!a && c)a = d[6] - c;
if (a && c && a + c != d[6])return;
if (d[7] && !b && d[7] - d[6] <= 0)return;
else if (d[7] && !b)b = d[7] - d[6];
if (d[7] && b && d[7] - b != d[6])return;
}
if (a > b || b > c || a > c) return;
if (a != d[1] && d[1])return;
if (b != d[2] && d[2])return;
if (c != d[3] && d[3])return;
if (a + b != d[4] && d[4])return;
if (b + c != d[5] && d[5])return;
if (a + c != d[6] && d[6])return;
if (a + b + c != d[7] && d[7])return;
for (int i = 1; i <= sum; i++)
{
if (ax[i] == a && bx[i] == b && cx[i] == c)return; //检查是否有重复
}
sum++, ax[sum] = a, bx[sum] = b, cx[sum] = c;
return;
}
for (int i = 1; i <= 7; i++)
{
if (d[i] == 0) {
d[i] = x[t];
if (d[1] <= d[2] || d[2] <= d[3]) {
dfs(t + 1);
}
d[i] = 0;
}
}
}
int main()
{
cin >> T;
vector<int> ans;
while (T--)
{
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> x[i];
d[i] = 0; // d[i]用来表示该位置的值是否已知,已知为该值,否则为0
}
sum = 0, dfs(1);
ans.push_back(sum);
}
for (int j = 0; j < ans.size(); j++) {
cout << ans[j] << endl;
}
return 0;
}