给一些线段,问所有相接能否构成正方形,注意给的线段要全部用完,本来以为是DP,后来发现DFS可以搞,开始直接裸搜的,数据一大就超时了,加了个剪枝条件,当前要加入的边不能大于前次加入的边,不加的话会有很多的重复搜索状态,剪枝后可以A了,MS时间上还不是很理想,应该还有更优的剪枝条件,暂时先这样了。。
#include<cstdio>
#include<map>
using namespace std;
namespace
{
struct cmp
{
bool operator()(const int x, const int y)
{
return x > y;
}
};
map<int, int, cmp> M;
int edge;
bool can;
void dfs(int depth, int len, int prev)
{
if (can)
return;
if (depth == 3)
{
can = true;
return;
}
for (map<int, int, cmp>::iterator it = M.begin(); it != M.end(); it++)
{
if ((*it).second && (*it).first + len <= edge
&& (!prev || (*it).first <= prev))
{
(*it).second--;
if ((*it).first + len == edge)
dfs(depth + 1, 0, 0);
else
dfs(depth, (*it).first + len, (*it).first);
(*it).second++;
}
}
}
}
int main()
{
int N, m, len;
scanf("%d", &N);
while (N--)
{
M.clear();
scanf("%d", &m);
int sum = 0, maxx = -1;
while (m--)
{
scanf("%d", &len);
if (M.find(len) == M.end())
M[len] = 1;
else
M[len]++;
sum += len;
if (len > maxx)
maxx = len;
}
if (sum % 4 || sum / 4 < maxx)
{
puts("no");
continue;
}
can = false;
edge = sum / 4;
dfs(0, 0, 0);
puts(can ? "yes" : "no");
}
return 0;
}