题意:
有一些木棍n个(大于等于4小于等于20),组成一个正方形(木棍全用完),是否能组成?
想法:
刚开始想的是四条边一起找,超时,最后看了别人的,每次找一条边+剪枝(每条边必须小于等于sum/4,sum为偶数),每次找时都从下一条木棍开始,最大的木棍小于等于sum/4;
代码实现:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX=23;
int n,Num[MAX],sum;
bool Visted[MAX],flag;
void DFS( int x, int len, int k )
{
if( flag )
return;
if( k==3 )
{
flag=1;
return;
}
if( len==sum )
{
DFS(0,0,k+1);
}
for( int i=x; i<n; ++i )
{
if( !Visted[i] && len+Num[i]<=sum)
{
Visted[i]=1;
DFS(i+1,len+Num[i],k);
Visted[i]=0;
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
int t;
scanf("%d",&t);
while( t-- )
{
scanf("%d",&n);
sum=0;
int Max=-1;
for( int i=0; i<n; ++i )
{
scanf("%d",&Num[i]);
sum+=Num[i];
Max=Max>Num[i]?Max:Num[i];
}
if( sum%4 || Max>sum/4 )
{
printf("no\n");
continue;
}
sum/=4;
memset(Visted,0,sizeof(Visted));
flag=0;
DFS(0,0,0);
if( flag )
printf("yes\n");
else
printf("no\n");
}
return 0;
}