给出一些不同长度的小棒,问小棒全部用完是否能构成一个正方形。
通过特判来起到剪枝的作用
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=25;
int a[maxn];
bool vis[maxn];
int n,l; //记录正方形边长
bool dfs(int pos,int pre,int cnt) //从该索引遍历、当前长度、已合成边长数量
{
if(cnt>=3) //剪枝
return 1;
for(int i=pos; i>=0; i--)
{
if(!vis[i])
{
vis[i]=1;
int now=pre+a[i];
if(now<l)
{
if(dfs(i-1,now,cnt)) //增加当前边的边长
return 1;
}
else if(now==l)
{
if(dfs(n-1,0,cnt+1)) //重新找最大边来合成新的边
return 1;
}
vis[i]=0;
}
}
return 0;
}
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
int sum=0,ma=0;
cin>>n;
for(int i=0; i<n; i++)
{
cin>>a[i];
sum+=a[i];
ma=max(ma,a[i]);
}
l=sum/4;
if(sum%4!=0||ma>l) //剪枝
{
cout<<"no"<<endl;
continue;
}
sort(a,a+n);
memset(vis,0,sizeof(vis));
if(dfs(n-1,0,0)) //从最长边开始遍历
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
return 0;
}