Square
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 13846 Accepted Submission(s): 4386
Problem 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
题意:给出n个木棍,能否用这n个木棍组成一个正方形,木棍要求全都用上。
分析:
简单的DFS题目,相当于是4个dfs,每个dfs扫描一条边,判断4条边都为总长度/4,则说明能组成正方形。我这里写成了一个,把边长当做了一个参数,每次扫到sum==half的时候,边长加1,sum清零,最后判断边长是否等于4即可。每扫一条边只需要扫一遍
0-n,为了这样处理,记录了上一层的加入边长的木棍下标i , 当做参数index(下次从index开始扫)。
代码如下:
#include <stdio.h>
#include <string.h>
int n;
int a[10005];
int ans[10005]; //标记该数字是否被用过
int half = 0;
int flag=0;
void dfs(int t,int sum,int peace,int index)
{//t代表扫过了几个,sum代表当前的长度,peace代表找完了几条边,index代表上一层扫描到的位置
if(flag)
return ;
if(sum==half)
{//当前长度等于half,代表一条边找完了
sum=0;
peace++;
index=0;
}
if(t==n)
{
if(peace==4)
flag=1;
return ;
}
for(int i=index;i<n;i++)
{
if(ans[i]==0 && sum+a[i]<=half)
{
ans[i]=1;
dfs(t+1,sum+a[i],peace,i+1);
ans[i]=0;
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
half=0;
for(int i=0;i<n;i++)
{
scanf("%d",a+i);
half+=a[i];
}
if(half%4!=0)
printf("no\n");
else
{
half/=4;
flag=0;
dfs(0,0,0,0);
if(flag)
printf("yes\n");
else
printf("no\n");
}
}
return 0;
}