给定一个非负整数数组 A,如果该数组每对相邻元素之和是一个完全平方数,则称这一数组为正方形数组。
返回 A 的正方形排列的数目。
两个排列 A1 和 A2 不同的充要条件是存在某个索引 i,使得A1[i]≠A2[i]。
输入格式
第一行包含一个整数 n,表示数组 AA的长度。
第二行包含 n 个整数 A[i]。
输出格式
一个整数,表示 A 的正方形排列的数目。
数据范围
1≤n≤12,
0≤A[i]≤109。
输入样例:
3
1 17 8
输出样例:
2
样例解释
[1,8,17] 和[17,8,1] 都是有效的排列。
代码:
// 注意判重的技巧 值相等的特殊处理
#include <bits/stdc++.h>
using namespace std;
const int N = 15;
int n;
int w[N];
bool st[N];
int ans;
bool check(int x)
{
int r = sqrt(x);
return x == r * r;
}
void dfs(int u, int last)
{
if (u == n)
{
ans++;
return;
}
for (int i = 0; i < n; i++)
{
if (st[i])
continue;
if (i && !st[i - 1] && w[i] == w[i - 1]) // 若前一个没有访问过且与当前的值相等 说明前一个已经搜索完了取消标记 则当前的不必再搜索
continue;
if (!check(w[i] + last))
continue;
st[i] = 1;
dfs(u + 1, w[i]);
st[i] = 0;
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
cin >> w[i];
sort(w, w + n);
for (int i = 0; i < n; i++)
{
if (!i || w[i] != w[i - 1]) // 防止有相同结果的排列
{
st[i] = true;
dfs(1, w[i]);
st[i] = 0;
}
}
cout << ans << endl;
return 0;
}