题目链接
题目大意:
给定一组木棍长度的数据,求是否能拼成一个正方形.
解题思路:
简单的DFS遍历就好了,但是本题要考虑剪枝
1)当所有木棍长度和sum, 需要满足sum%4 = 0,否则拼不成正方形。
2)最长的木棍要满足小于边长side = sum / 4。
在1)2)条件下进行DFS遍历,可以减小时间复杂度。
#include <iostream>
using namespace std;
int size, N, sum;
int maxLen = 0;
int stickLen[21];
int visit[21];
bool dfs(int cnt, int left, int begin)
{
bool flag;
if(cnt == 4) return true;
for(int i = begin; i < N; i++)
{
if(visit[i] == 0)
{
visit[i] = 1;
if(stickLen[i] == left)
{
flag = dfs(cnt + 1, sum / 4, 0);
if(flag) return true;
}
else if(stickLen[i] < left)
{
flag = dfs(cnt, left - stickLen[i], i + 1);
if(flag) return true;
}
visit[i] = 0;
}
}
return false;
}
int main()
{
bool flag;
freopen("input.txt", "r", stdin);
cin >> size;
while(size--)
{
sum = 0;
maxLen = 0;
cin >> N;
for(int i = 0; i < N; i++)
{
cin >> stickLen[i];
sum += stickLen[i];
if(maxLen < stickLen[i])
{
maxLen = stickLen[i];
}
}
if(sum % 4 != 0 || maxLen > sum /4)
{
cout << "no" << endl;
continue;
}
memset(visit, 0, sizeof(visit));
flag = dfs(1, sum/4, 0);
if(flag)
cout << "yes" << endl;
else
cout << "no" << endl;
}
return 0;
}