Total Submit: 18 Accepted: 9
4≤M≤20, the number of sticks. M integers follow; each gives the length of a stick - an integer
between 1 and 10000.
4 1 1 1 1
5 10 20 30 40 50
8 1 7 2 6 4 4 3 5
no
yes
#include <iostream>
#include <string>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <string>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
int n;//棍子的个数;
int sum;//总的长度;
int l[25];//放棍子;
int used[25];//是否被使用;
int bian;//每条边的长度;
bool ok;//是否可以组成正方形;
bool cmp(int a,int b){
return a>b;
}
void DFS(int i,int cnt,int nlen){//i代表从用的第几个棍子,cnt代表已经组成的边的个数,nlen代表当前组成的长度;
if(cnt==3){
ok=1;
return ;
}
if(ok==0){
for(int j=i;j<n;j++){//从j个棍子找起;
if(!used[j] && nlen+l[j]<=bian){//如果当前棍子未被使用,并且其和小于边长;
used[j]=1;//标记为使用;
if(nlen+l[j]==bian)
DFS(0,cnt+1,0);//找到一边,重新开始找下一边;
else
DFS(j+1,cnt,nlen+l[j]);//否则找下一个棍子;
used[j]=0;//传说中的回溯= =……;
}
}
}
}
int main(){
int t;
scanf("%d",&t);//t个总数;
while(t--){
ok=0;
sum=0;//总数清空……刚开始没清空…… 过了组BT的…… 屁颠屁颠的去交…… 差点WA一次……
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&l[i]);
sum+=l[i];
}
sort(l,l+n,cmp);
if(sum%4!=0){//如果无法被4整出,则无法构成正方形;
puts("no");
continue;
}
else{
bian=sum/4;
if(l[0]>bian){//如果最长的比边长大,必然无法构成正方形;
puts("no");
continue;
}
DFS(0,0,0);
if(ok==1)
puts("yes");
else
puts("no");
}
}
}