Square
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 19506 | Accepted: 6781 |
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
Source
#include <iostream>
#include "algorithm"
#include "cstdio"
#include "cmath"
#include "cstring"
using namespace std;
int a[50], vis[50];
int M, len, side, num;
bool com(int a, int b)
{
return a > b;
}
bool DFS(int start, int len, int num)
{
int i;
if(num == 3) return true;
for(i = start; i <= M; i++)
{
if(vis[i]) continue;
vis[i] = true;
if(len + a[i] < side)
{
if(DFS(i+1, len+a[i], num)) return true;
}
else if(len + a[i] == side)
{
if(DFS(1, 0, num+1)) return true;
}
vis[i] = false;
}
return false;
}
int main()
{ //freopen("in.txt", "r", stdin);
int T;
int i;
scanf("%d", &T);
while(T--)
{ int sum = 0;
num = 0;
len = 0;
memset(vis, 0, sizeof(vis));
scanf("%d", &M);
for(i = 1; i <= M; i++)
{
scanf("%d", &a[i]);
sum += a[i];
}
side = sum/4;
sort(a+1, a+M+1, com);
if(sum%4 != 0) { cout<<"no"<<endl; continue; }
if(side < a[1]) { cout<<"no"<<endl; continue; }
if(DFS(1, len, num)) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
return 0;
}