/*此题刚看时真没思路,搜了下别人的解题报告才有思路,还是用了个多小时
题意:给出很多棍子,问能否正好拼出个正方形
此题用回溯,一个数一个数的搜,如果之和为正好为给出所以数总数的1/4,则边数加一;
*/#include<iostream>
using namespace std;
int n,m;
int sum,len;
int a[22],v[22];
int ok;
void dfs(int cur,int l,int b)//cur 第几条边,l 当前边的长度,b,数组中第几个,其实可以不要这个,但会超时,因为访问过的就不必再访问
{
if(l==sum/4)
dfs(cur+1,0,0);
if(cur==4)
{
ok=1;
return ;
//cout<<"yes"<<endl;
//break;
}
if(ok==1)//保证能跳出
return ;
if(cur!=4)
{
for(int i=b;i<n;i++)
if(!v[i]&&l+a[i]<=sum/4)
{
v[i]=1;
dfs(cur,l+a[i],i);
v[i]=0;
}
}
}
int main()
{
int t,i,j;
cin>>t;
while(t--)
{
cin>>n;
sum=0;
len=0;
for(i=0;i<n;i++)
{
cin>>a[i];
sum+=a[i];
ok=0;
if(a[i]>len)
len=a[i];
}
if(len>sum/4||sum%4!=0)//小小的剪枝
cout<<"no"<<endl;
else
{
memset(v,0,sizeof(v));
dfs(0,0,0);
if(ok)
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
}
return 0;
}
题意:给出很多棍子,问能否正好拼出个正方形
此题用回溯,一个数一个数的搜,如果之和为正好为给出所以数总数的1/4,则边数加一;
*/#include<iostream>
using namespace std;
int n,m;
int sum,len;
int a[22],v[22];
int ok;
void dfs(int cur,int l,int b)//cur 第几条边,l 当前边的长度,b,数组中第几个,其实可以不要这个,但会超时,因为访问过的就不必再访问
{
if(l==sum/4)
dfs(cur+1,0,0);
if(cur==4)
{
ok=1;
return ;
//cout<<"yes"<<endl;
//break;
}
if(ok==1)//保证能跳出
return ;
if(cur!=4)
{
for(int i=b;i<n;i++)
if(!v[i]&&l+a[i]<=sum/4)
{
v[i]=1;
dfs(cur,l+a[i],i);
v[i]=0;
}
}
}
int main()
{
int t,i,j;
cin>>t;
while(t--)
{
cin>>n;
sum=0;
len=0;
for(i=0;i<n;i++)
{
cin>>a[i];
sum+=a[i];
ok=0;
if(a[i]>len)
len=a[i];
}
if(len>sum/4||sum%4!=0)//小小的剪枝
cout<<"no"<<endl;
else
{
memset(v,0,sizeof(v));
dfs(0,0,0);
if(ok)
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
}
return 0;
}