题目来源:http://poj.org/problem?id=2362
跟poj1011, nyoj 293大体思路一样!
但是这个题要有自身的剪枝!:http://blog.csdn.net/hearthougan/article/details/22986249
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 25;
int Len_Of_Sticks[MAXN];
bool visit[MAXN];
int num;
bool DFS(int CurLen, int kcount, int pos, int EdgeLen)
{
if(kcount == 3)//有三条边满足,没那么就可以组成正方形,新加判别条件
return true;
for(int i = pos; i < num; ++i)
{
if(!visit[i])
{
if(Len_Of_Sticks[i] + CurLen == EdgeLen)
{
visit[i] = true;
if(DFS(0, kcount+1, 0, EdgeLen))
return true;
visit[i] = false;
return false;
}
else if(Len_Of_Sticks[i] + CurLen < EdgeLen)
{
visit[i] = true;
if(DFS(Len_Of_Sticks[i] + CurLen, kcount, i+1, EdgeLen))
return true;
visit[i] = false;
bool flag = (CurLen == 0 ? true : false);
if(flag)
return false;
while(Len_Of_Sticks[i] == Len_Of_Sticks[i+1])
++i;
}
}
}
return false;
}
int cmp(int a, int b)
{
return a > b;
}
int main()
{
int T, sum, Edge;
int i;
scanf("%d", &T);
while(T--)
{
scanf("%d", &num);
sum = 0;
for(i = 0; i < num; ++i)
{
scanf("%d", &Len_Of_Sticks[i]);
sum += Len_Of_Sticks[i];
}
if(num < 4 || sum % 4 != 0)//边数小于4 || 长度之和不能被4整除自然不可以
{
printf("no\n");
continue ;
}
memset(visit, false, sizeof(visit));
sort(Len_Of_Sticks, Len_Of_Sticks+num, cmp);
Edge = sum/4;
if(Edge < Len_Of_Sticks[0])//最长的小棒不能大于边!!!
{
printf("no\n");
continue ;
}
if(DFS(0, 0, 0, Edge))
printf("yes\n");
else
printf("no\n");
}
return 0;
}