Description
Problem C: Square
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
4 1 1 1 1
5 10 20 30 40 50
8 1 7 2 6 4 4 3 5
Sample Output
yes
no
yesd
该题考察深度搜索和回溯,为了避免超时,在搜索之前进行剪枝。例如这题,题意:给出一些长度,看能否围成正方形,
我们可以先计算每个边的边长看是否是整数,因为长度不可分割,所以如果不是整数,就直接输出"no",如果其中一个长度
大于平均长度,也不能构成正方形,输出"no",然后再进行dfs(0,0,0)搜索。
no
yesd
该题考察深度搜索和回溯,为了避免超时,在搜索之前进行剪枝。例如这题,题意:给出一些长度,看能否围成正方形,
我们可以先计算每个边的边长看是否是整数,因为长度不可分割,所以如果不是整数,就直接输出"no",如果其中一个长度
大于平均长度,也不能构成正方形,输出"no",然后再进行dfs(0,0,0)搜索。
#include <cstring>
#include <iostream>
using
namespace
std;
int
a[21], vis[21];
int
flag, sum, ave, n;
void
dfs(
int
x,
int
y,
int
p)
{
int
i;
if
(x==4)
{
flag=1;
return
;
}
if
(y==ave)
{
dfs(x+1,0,0);
//从0开始重新搜索
if
(flag)
return
;
}
for
(i=p; i<n;i++)
{
if
(!vis[i]&&y+a[i]<=ave)
{
vis[i]=1;
dfs(x,a[i]+y,i+1);
if
(flag)
return
;
vis[i]=0;
}
}
}
int
main()
{
int
T, i;
while
(cin>>T)
{
while
(T--)
{
memset
(vis,0,
sizeof
(vis));
sum=0,flag=0;
cin>>n;
for
(i=0;i<n;i++)
{
cin>>a[i];
sum+=a[i];
}
if
(sum%4!=0)
{
cout<<
"no"
<<endl;
continue
;
}
ave=sum/4;
for
(i=0;i<n;i++)
{
if
(a[i]>ave)
{
flag=1;
break
;
}
}
if
(flag==1)
{
cout<<
"no"
<<endl;
continue
;
}
dfs(0,0,0);
if
(flag)
cout<<
"yes"
<<endl;
else
cout<<
"no"
<<endl;
}
}
return
0;
}