題目:已知一些木棍,問能否拼成一二正方形。
分析:搜索。求木棍能否組成四根長度相同的長棍子。
剪枝:1.排序,預處理;
2.如果相同長度前面的沒選,後面的不會選;
3.如果發現構造一根長棍子失敗,則不會成功;
4.在構造一根長棍子時,按照順序取小棍子;
說明:╮(╯▽╰)╭。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int stick[22];
int visit[22];
bool cmp(int a, int b)
{
return a > b;
}
int dfs(int max, int n, int s, int d, int sum)
{
if (d == 3) {
return 1;
}
for (int i = s; i < n; ++ i) {
if (visit[i] || i && !visit[i-1] && stick[i] == stick[i-1]) {
continue;
}
visit[i] = 1;
if (sum + stick[i] == max) {
if (dfs(max, n, 0, d+1, 0)) {
return 1;
}
}else if (sum + stick[i] < max) {
if (dfs(max, n, i+1, d, sum+stick[i])) {
return 1;
}
}
visit[i] = 0;
if (!sum) {
return 0;
}
}
return 0;
}
int main()
{
int N, M, sum;
while (~scanf("%d",&N)) {
while (N --) {
scanf("%d",&M);
sum = 0;
for (int i = 0; i < M; ++ i) {
scanf("%d",&stick[i]);
sum += stick[i];
visit[i] = 0;
}
sort(stick, stick+M, cmp);
if (sum%4 || stick[0] > sum/4) {
puts("no");
}else {
if (dfs(sum/4, M, 0, 0, 0)) {
puts("yes");
}else {
puts("no");
}
}
}
}
return 0;
}