【POJ】2362 Square(DFS)
【题目链接】http://poj.org/problem?id=2362
题目内容
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根木棍问能不能拼出正方形
解题思路
如果木棍长度总和不是4的倍数,直接排除,不然长度和/=4,如果能dfs构成三条边,就能构成正方形。
具体的dfs过程见注释。
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<math.h>
#include<limits.h>
#include<stack>
#include<queue>
#define LL long long
using namespace std;
int a[25];
int b[25];标记木棍i有没有被用过
bool cmp(int a,int b)
{
return a>b;
}
int n,sum;
bool flag;
void dfs(int x,int i,int num)//x是已经拼好的长度,i是待检测的木棍,num是已经拼好的边的数量;
{
if(num==3||flag)
{
flag=true;
return;
}
for(int j=i;j<n;j++)
{
if(a[j]>sum-x) return;
if(b[j]==0&&a[j]==sum-x)
{
b[j]=1;
dfs(0,0,num+1);
b[j]=0;
return;
}
if(b[j]==0&&a[j]<sum-x)
{
b[j]=1;
dfs(x+a[j],j+1,num);
if(flag) return;
b[j]=0;
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
sum=0;
flag=false;
memset(b,0,sizeof(b));
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
if(sum%4!=0)
{
printf("no\n");
continue;
}//排除总长度不是4的倍数的情况
sum/=4;
sort(a,a+n);
if(a[n-1]>sum)
{
printf("no\n");
continue;
}
dfs(0,0,0);
if(flag)
printf("yes\n");
else printf("no\n");
}
return 0;
}