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
万恶的BZOJ几分钟内就封了,哎,只能先玩POJ了。
分析:dfs可以解决,因为数据量小,所以不用剪枝也能AC。
代码如下:
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int T,N,a[30],f[30];
int maxx,minn,sum;
bool DFS(int x,int num,int tot)
{
if(tot==sum) num++,tot=x=0;
if(minn+tot>sum) return 0;
if(num==3) return 1;
int last=-1;
for(int i=x+1;i<=N;i++)
if(!f[i])
{
if(a[i]==last)continue;
f[i]=1;
if(DFS(i,num,tot+a[i])) return 1;
f[i]=0;
last=a[i];
}
return 0;
}
int main()
{
scanf("%d",&T);
while(T--)
{
memset(f,0,sizeof(f));
scanf("%d",&N);
minn=10000000,maxx=sum=0;
for(int i=1;i<=N;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
maxx=max(a[i],maxx);
minn=min(a[i],minn);
}
sort(a+1,a+N+1,greater<int>());
if(sum%4)
{
printf("no\n");
continue;
}
sum/=4;
if(maxx>sum)
{
printf("no\n");
continue;
}
f[1]=1;
if(DFS(1,0,a[1])) printf("yes\n");
else printf("no\n");
}
return 0;
}