给 n 个木棒的长度,问能否拼成正方形(不许裁剪)
其实思路很好想,但是有几处剪枝要注意:
所有木棍都要用上,越长的木棍灵活度越小,所以要先用长的。
当 sum 不能整除时,或最长的木棍比边长还长时,显然不可以
当凑齐了三条边时,若满足 sum 可以整除,第四条边就不需要计算了
木棍必须有 4 根或以上
const int N=20+5;
int n,m,t;
int i,j,k;
int a[N];
bool vis[N],flag;
int sum,side;
void DFS(int num,int len,const int lock)
//num已完成的边数,len当前长度,lock为开始搜索的位置,也可以理解为所枚举到木棍的编号
{
if(flag) return ;
if(num==3 && len==0){
flag=1;
return ;
}
for(int i=lock;i<n;i++){
if(vis[i]) continue;
vis[i]=1;
if(len+a[i]==side) DFS(num+1,0,0);
else if(len+a[i]<side) DFS(num,len+a[i],i);
vis[i]=0;
}
return ;
}
int main()
{
//IOS;
rush(){
sd(n);
sum=0;
for(i=0;i<n;i++) { sd(a[i]); sum+=a[i]; }
if(sum%4 || n<4){ puts("no"); continue; }
side=sum/4;
sort( a,a+n,greater<int>() );
if(a[0]>side){ puts("no"); continue; }
flag=0;
DFS(0,0,0);
puts(flag?"yes":"no");
}
//PAUSE;
return 0;
}