前面用迭代不知道为什么出错,后来改用递归
算法思想:
首先若木棒长度和不是4的整数倍则不可能构成正方形,逐条边填充,如遇到一条边不能填充则CUT
考虑几种分支情况:
如果当前边剩余空间为0
若剩余木棒也为0,则已经填充完毕(此时一定恰好填充了4条边)
否则填充下一条边
对每条边设立使用标记,从未使用的第一条边开始逐个填入,填入时将访问标记设为true(之后归还),递归填其余边
如果剩余木棒可以填充在剩余空间中,则直接返回TRUE
如果不能填充,取消当前木棒,若当前木棒已经填满某条边,则其余木棒不用再填充(取掉之后也一样)
如果下一条木棒和当前木棒相同,则也不用比较
代码:
# include <iostream>
# include <vector>
# include <algorithm>
# include <queue>
using namespace std;
int EdgeLength = 0;
vector<int> stickStorage;
vector<bool> usage;
bool pathFinder(int stickRemain, int spaceRemain, int subscription)
{
int spcR = spaceRemain;
int stkR = stickRemain;
if ( spaceRemain == 0 )
{
if ( stickRemain == 0 )
{
return true;
}
spcR = EdgeLength;
subscription = 0;
}
int size = stickStorage.size();
for ( int i = subscription ; i < size; i++ )
{
if ( usage[i] == false && stickStorage[i] <= spcR )
{
usage[i] = true;
if ( pathFinder(stkR-1,spcR-stickStorage[i],i+1) )
{
return true;
}
usage[i] = false;
if ( stickStorage[i] == spcR || spcR == EdgeLength ) //If the current stick fills a line, there's no need to compare any more
{
break;
}
while ( stickStorage[i] == stickStorage[i+1] && i < size-1 )
{
i++;
}
}
}
return false;
}
int main()
{
int n = 0;
int stickNum = 0;
int currentStickLen = 0;
bool possible = false;
int sum = 0;
cin >> n;
int j = 0;
for ( int i = 0; i < n; i++ )
{
possible = false;
EdgeLength = 0;
sum = 0;
stickStorage.clear();
usage.clear();
cin >> stickNum;
for ( j = 0; j < stickNum; j++ )
{
cin >> currentStickLen;
sum += currentStickLen;
stickStorage.push_back(currentStickLen);
usage.push_back(false);
}
sort(stickStorage.begin(),stickStorage.end(),greater<int>());
if ( sum%4 != 0 )
{
possible = false;
}
else
{
EdgeLength = sum/4;
possible = pathFinder(stickStorage.size(),EdgeLength,0);
}
if ( possible )
{
cout << "yes" << endl;
}
else
{
cout << "no" << endl;
}
}
return 0;
}