思路:从第一个数开始搜索,将其和与边长比对,相等则计数+1,计数达到3的时候说明可以组成,因为剩下那条必与边长相等,搜索过程注意剪枝,若某个数已被加入边长则不能重复计算,应将其标记,另外应在每一层递归时进行判断,看是否满足结束条件,以此来优化时间
#include<stdio.h> #include<string.h> int a[25],vis[25]; int con,temp,side,sum,flag,k; //con用来记录边数,temp存放暂时的边长,用来与目标边长比对,index是每次查找的起始点(从上次结束的位置),非常重要,用此优化时间 void dfs(int con,int temp,int index) { int i; if(3==con) { flag =1; return; } if(temp==side) { dfs(con+1,0,0); if(flag) return; } for(i = index ;i < k;i++) { if(!vis[i]) //判断此数是否已被用过 { vis[i]=1; dfs(con,temp+a[i],i+1); if(flag) return; vis[i]=0; } }}int main(){ int n,m,max; scanf("%d",&n); while(n--) { k = sum =0; flag = max =0; memset(vis,0,sizeof(vis)); scanf("%d",&m); while(m--) { scanf("%d",&a[k++]); sum += a[k-1]; if(max<a[k-1]) max = a[k-1]; } if(sum%4||max>sum/4) { printf("no "); continue; } side = sum/4; dfs(0,0,0); if(flag) { printf("yes "); continue; } printf("no "); } return0;}