HDU

来源:互联网 发布:血源诅咒捏脸美女数据 编辑:程序博客网 时间:2024/06/10 22:43

Square

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

题目大意:
给了很多段长度的小木棒,问能不能拼成一个正方形。

解题思路:
1.首先将长度累加,看是不是4的倍数,不是的话就直接不可能了。是的话就求出边长。
2.开始暴力搜索,对每段长度进行DFS,直到出现有一个边凑不成指定边长,说明不可能。
3.可以进行多种剪枝方法比如: 排序,从大到小搜索。 跳过重复的不匹配边。 此处给出一个链接,这道题方法类似但是剪枝要求很高,看了很多题解觉的这篇的源码和思路都写的比较易懂: POJ 1011 Sticks【DFS+剪枝】


源代码:

#include<iostream>#include<stdio.h>#include<cstring>#include<string.h>#include<vector>using namespace std;bool use[24];int length[24];int num, avg;bool dfs(int i, int now, int count) {    if (now == avg) {        i = 0;        now = 0;        if (++count == 4)            return true;    }    for (int j = i; j < num; j++) {        if (!use[j]) {            use[j] = true;            if (now + length[j] <= avg  && dfs(j+1, now + length[j], count))                return true;            use[j] = false;        }    }    return false;}int main() {    int times, n, start,total;    scanf("%d", &times);    for (int ti = 1; ti <= times; ti++) {        memset(use, false, sizeof(use));        scanf("%d", &num);        total = 0;        for (int i = 0; i < num; i++) {            scanf("%d", &length[i]);            total += length[i];        }        bool result = false;        if (total % 4 == 0) {            avg = total / 4;            result = dfs(0, 0, 0);        }        if (result)            printf("yes\n");        else            printf("no\n");     }    return 0;}
原创粉丝点击