HDU1518

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
一万点尴尬,越搜越晕
//构造四条边 //如果加和不是四的倍数显然不能构成 //边的长度大于四分之一总和也不能构成 //构成一条边,继续递归搜索时,长度变成0,继续从第一个位置进行搜索 //直到bian == 4,立个flag,结束
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <fstream>
int in[22];
int vis[22];
int flag;
int pd, num, sum;
using namespace std;

void sear(int bian, int line, int place)
{
    if(bian == 4)
    {
        flag = 1;
        return;
    }
    if(line == pd)
    {
        sear(bian + 1, 0, 0);
        if(flag)
            return;
    }
    for(int i = place; i < num; i++)
    {
        if(!vis[i] && (line + in[i])<= pd)
        {
            vis[i] = 1;
            sear(bian, line + in[i], i + 1);
            //如果上面那种情况符合条件,不再继续判断
            if(flag)
                return;
            vis[i] = 0;
        }
    }
    return;
}
int main()
{
    //freopen("in.txt", "r", stdin);
    int n;
    scanf("%d", &n);
    while(n)
    {
        n--;
        sum = 0;
        scanf("%d", &num);
        for(int i = 0; i < num; i++)
        {
            scanf("%d", &in[i]);
            sum += in[i];
        }
        if(sum % 4 != 0)
            printf("no\n");
        else
        {

            pd = sum / 4;
            //printf("%d\n", pd);
            int i;
            for(i = 0; i < num; i++)
            {
                if(in[i] > pd)
                    break;
            }
            if(i != num)
            {
                printf("no\n");
                continue;
            }
            memset(vis, 0, sizeof(vis));
            flag = 0;
            sear(0, 0, 0);
            if(flag)
                printf("yes\n");
            else
                printf("no\n");
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值