Problem Description
Given a set of sticks of various lengths, is it possible to join them end-to-end to form a square?
Input
The first line of input contains N, the number of test cases. Each test case begins with an integer 4 <= M <= 20, the number of sticks. M integers follow; each gives the length of a stick - an integer between 1 and 10,000.
Output
For each case, output a line containing "yes" if is is possible to form a square; otherwise output "no".
Sample Input
3 4 1 1 1 1 5 10 20 30 40 50 8 1 7 2 6 4 4 3 5
Sample Output
yes no yes
题意:判断所给的几个数能否组成一个正四边形
思路:从题意可以看出,要成为正四边形,那么必须所给的数之和能别4整除,而且所给的数中最小的数不能大于正四边形的边长。然后通过深搜遍历每个数,直到组合成边长的长度为止,最后通过统计组成边长的个数,判断是否满足条件
import java.util.Scanner;
public class P1518 {
public static int m,edglen;
public static int[] visit;
public static int[] a;
public static boolean flag;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
while(n-->0){
m=sc.nextInt();
a=new int[m];
visit=new int[m];
int sum=0;
flag=false;
for(int i=0;i<m;i++){
a[i]=sc.nextInt();
sum+=a[i];
}
if(sum%4!=0){//剪枝,总和不能被4整除,则一定不能组成
System.out.println("no");
continue;
}
edglen=sum/4;
sort();
if(edglen<a[0]){//最小的都大于边长,减去
System.out.println("no");
continue;
}
DFS(0,a[0],0);
if(flag){
System.out.println("yes");
}else{
System.out.println("no");
}
}
}
private static void DFS(int edglenNumb, int edg, int i) {
int k=i;
visit[i]=1;
if(edg==edglen){
edglenNumb++;
k=0;
edg=0;
}
if(edglenNumb==3){
flag=true;
return;
}
for(int j=k;j<m;j++){
if(visit[j]==0 && edg+a[j]<=edglen){
DFS(edglenNumb,a[j]+edg,j);
if(flag){
return ;
}
}
}
visit[i]=0;
}
private static void sort() {
for(int i=0;i<m-1;i++){
for(int j=0;j<m-1-i;j++){
if(a[i]>a[j]){
int t=a[i];a[i]=a[j];a[j]=t;
}
}
}
}
}