使得给出的若干木棍可以拼出正方形,搜索回溯,注意剪枝。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
int num, lenth;
int a[21], cct;
bool vis[21], flag;
int cmp(const void *x, const void *y)
{
return *(int*)y - *(int*)x;
}
void dfs(int s, int cur)
{
if(cct == 4)
{
flag = true;
return ;
}
if(!flag)
for(int i=cur; i<num; i++)
if(!vis[i])
{//回溯
if(s+a[i]==lenth)
{
++cct;
vis[i] = true;
dfs(0, 0);
--cct;
vis[i] = false;
if(flag)
break;
}
else if(s+a[i]<lenth)
{
vis[i] = true;
dfs(s+a[i], i+1);
vis[i] = false;
}
}
}
int main()
{
#ifdef test
freopen("sample.txt", "r", stdin);
#endif
int t, sum;
scanf("%d", &t);
while(t--)
{
int Max = 0;
flag = cct = sum = 0;
memset(vis, 0, sizeof(vis));
scanf("%d\n", &num);
for(int i=0; i<num; i++)
{
scanf("%d", &a[i]);
sum += a[i];
}
lenth = sum / 4;
qsort(a, num, sizeof(a[0]), cmp); //从大到小排序
if(sum%4 || a[0]>lenth) //不能整除4或是最大值大于边长,则肯定无法构成正方形
{
printf("no\n");
continue;
}
dfs(0, 0);
if(flag)
printf("yes\n");
else
printf("no\n");
}
return 0;
}