原题链接: [http://acm.hdu.edu.cn/showproblem.php?pid=1518](http://acm.hdu.edu.cn/showproblem.php?pid=1518)
**一:原题内容**
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
~~~
**二:理解分析**
给定一堆棍子,问是否能构造出一个正方形,当然所有棍子都要使用。首先判断所有棍子长度是否能整除4,不能的话,肯定不是正方形,其次棍子中最长的那根,是否大于正方形的边长呢?大于的话,当然也是不能组成正方形的。
**三:AC代码**
~~~
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
bool visit[21];
int square[21];
int N;
int M;
int sum; //周长长度
int len; //边长长度
bool flag; //标记是否已找到正方形
void DFS(int, int, int);
int main()
{
scanf("%d", &N);
while (N--)
{
scanf("%d", &M);
memset(visit, 0, sizeof(visit));
sum = 0;
flag = false;
for (int i = 0; i < M; i++)
{
scanf("%d", &square[i]);
sum += square[i];
}
sort(square, square + M);//排序
len = sum / 4;//求出边长
if (sum % 4 == 0 && square[M - 1] <= len)//周长能整除4且所给长度的最大值小于等于边长才有可能构造出正方形
DFS(0, M - 1, 0);
if (flag)
printf("yes\n");
else
printf("no\n");
}
return 0;
}
void DFS(int sideLen, int k, int number)//sideLen代表当前正在构造的边长长度;number标记当前已经有多少条边构造出来了,当有三条边已构造出来,那么根据正方形的性质,说明此时这些棍子是可以组成正方形的
{
if (sideLen == len)//已成功构造出一条边长
{
number++;//这个地方起初是设置为全局变量(也就是DFS函数的第三参数起初是没有的),但是交上去WA了,最后才发现是这里错了。
sideLen = 0;
k = M - 1;
}
if (number == 3)//正方形已构造出
{
flag = 1;
return;
}
if (flag)
return;
for (int i = k; i >= 0; i--)
{
if (!visit[i] && square[i] + sideLen <= len)//如果这根棍子没有使用过并且当前正在构造的边长加上这个棍子的总长度也是不大于边长的,那就可以了
{
visit[i] = 1;
DFS(sideLen + square[i], i - 1, number);
if (flag)
return;
visit[i] = 0;
while (square[i - 1] == square[i])
i--;
if (len - sideLen == square[i])
return;
if (sideLen == 0)
return;
}
}
}
~~~
参考链接: [http://www.acmerblog.com/hdu-1518-Square-2075.html](http://www.acmerblog.com/hdu-1518-Square-2075.html)