搜索经典题,与pku acm_1011题类似。
写得有点拗手,一开始都不知道跳到哪里去了,还得参考了很久以前做的1011题的源码,还得多多练习啊~
详细代码:
#include <iostream>
#include <algorithm>
using namespace std;
int n,m, s[25],sum;
bool mark[25];
bool cmp(int a, int b){
return a > b;
}
bool DFS(int cur_len, int k, int cur_num){
if (cur_num == 4) return true; //4条边全部还原成功,返回true
else if (cur_len == sum) return DFS(0, 0, cur_num + 1); //已完成当前一条边,还原下一条边
else{
int i;//pre,pre = 0,
for (i = k; i < m; i++)
{
if (mark[i] && s[i] + cur_len <= sum){//当前木棍可用 //&& s[i] != pre
//pre = s[i];
mark[i] = false; //改变使用状态
if (DFS(cur_len + s[i], i + 1, cur_num)) break; //递归检测下一条木棍
mark[i] = true; //如果使用当前的木棍并不能成功还原的话,还原此木棍状态
if (k == 0) return false; //回溯到第一根木棍仍然不能成功还原时,返回false
}
}
if (i == m) return false; //一直到循环结束都无法还原边,则return false
else return true;
}
}
int main(){
cin>>n;
while(--n>=0)
{
cin>>m;
for (int i = sum = 0; i < m; i++)
{
cin>>s[i];
sum += s[i];
}
if(sum%4!=0)
{printf("no/n");continue;}
sort(s, s + m, cmp);
sum /= 4;
memset(mark, true, sizeof(mark));
if(DFS(0, 0, 0))printf("yes/n");
else printf("no/n");
}
return 0;
}