Language:
Square
Description
Given a set of sticks of various lengths, is it possible to join them end-to-end to form a square?
Input
The first line of input contains N, the number of test cases. Each test case begins with an integer 4 <= M <= 20, the number of sticks. M integers follow; each gives the length of a stick - an integer between 1 and 10,000.
Output
For each case, output a line containing "yes" if is is possible to form a square; otherwise output "no".
Sample Input 3 4 1 1 1 1 5 10 20 30 40 50 8 1 7 2 6 4 4 3 5 Sample Output yes no yes Source |
《搜索是怎样剪枝的-1》
1.只要找到3条边。
2.从大到小顺序找。
3.每次搜边时要确定边的相对顺序唯一(直接从TLE→秒)
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cstring>
#include<iostream>
using namespace std;
#define MAXM (20+10)
int tt,n,a[MAXM],cnt,len;
bool b[MAXM],flag;
bool dfs(int l,int x,int pre)
{
// cout<<l<<' '<<x<<' '<<kth<<endl;
if (x==len) {l++;x=0;pre=n-1;}
if (l==4)
{
return 1;
}
for(int i=pre-1;i;i--)
if (!b[i]&&x+a[i]<=len)
{
b[i]=1;
if (dfs(l,x+a[i],i)) return 1;
b[i]=0;
// if (!x) return 0;
}
return 0;
}
int main()
{
scanf("%d",&tt);
while (tt--)
{
cnt=0;
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
cnt+=a[i];b[i]=0;
}
sort(a+1,a+1+n);
if (n<4||cnt%4||a[n]>cnt/4)
{
printf("no\n");continue;
}
b[n]=1;len=cnt/4;
if (dfs(1,a[n],n))
{
printf("yes\n");
}
else printf("no\n");
}
return 0;
}