AcWing每日一题 2022.7.19

DFS + 排序剪枝

排序剪枝:为了防止同一个序列被枚举多次,先排序,对于相同的数,只枚举出现的第一次。
对于dfs内部的排序,同样只枚举出现的第一次,但是是对于本次枚举出现的第一次,之前已经确定在序列中的不需要考虑。
由于每次枚举只考虑最先出现的那个,所以这个结构是可以迭代执行而不出错的。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 20;

int n;
int a[N];
int st[N];
LL ans;

bool judge(int x) {
	if ((int)sqrt(x) * (int)sqrt(x) == x)
		return true;
	return false;
}

void dfs(int p, int pre) {
	if (p >= n) {
		ans++;
		return ;
	}

	for (int i = 1; i <= n; i++) {
		if (!st[i]) {
			if (i > 1 && !st[i - 1] && a[i] == a[i - 1])
				continue;
			if (judge(a[pre] + a[i])) {
				st[i] = 1;
				dfs(p + 1, i);
				st[i] = 0;
			}
		}
	}

	return ;
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
		scanf("%d", &a[i]);

	sort(a + 1, a + 1 + n);
	for (int i = 1; i <= n; i++) {
		if (i > 1 && a[i] == a[i - 1])
			continue;
		st[i] = 1;
		dfs(1, i);
		st[i] = 0;
	}

	printf("%lld\n", ans);

	return 0;
}
posted @ 2022-07-19 15:15  superPG  阅读(16)  评论(0编辑  收藏  举报