POJ 2362 Square

题目大意:

给定一些木棒,问是否可以用这些木棒头尾相连成一个正方形。

解题思路:

DFS+剪枝

本题可以理解为把这些木棒拼接成四根长度相同的大木棒,所有木棒的总长度sum为正方形周长,sum/4是变长

不难看出,小棒的长度越长,灵活性越差,由此,我们要对这些木棒进行降序排序,从最长的棒子DFS

剪枝:

1、要组合成正方形,必须满足sum%4==0;

2、所有小棒中最长的一根Max_length<=sum/4;

3、当满足1,2时,只需能组合成三条边,就能确定这些棒子能拼成正方形;

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n,sticks[30];
int vis[30];
int sum,num;
bool cmp(int n,int m){
    return n>m;
}
bool dfs(int num,int len,int st){  //num:已组合的正方形的边数;len:当前正在组合的边的已组合长度;
                                    //st:sticks[]的搜索起点
    if(num==3){            //剪枝3,当满足剪枝1和剪枝2的要求时,只需组合三条边,剩下的木棒必能组合成
        return true;       //另一条边;
    }
    for(int i=st;i<n;i++){
        if(vis[i]){
            continue;
        }
        vis[i]=true;
        if(len+sticks[i]<sum){
            if(dfs(num,len+sticks[i],i+1))  //继续构建当前边
                return true;
        }
        else if(len+sticks[i]==sum){
            if(dfs(num+1,0,0)){    //构建新的边
                return true;
            }
        }
        vis[i]=false;
    }
    return false;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        sum=0;
        for(int i=0;i<n;i++){
            scanf("%d",&sticks[i]);
            sum+=sticks[i];
        }
        if(sum%4){    //剪枝1
            printf("no\n");
            continue;
        }
        sort(sticks,sticks+n,cmp);   
        sum/=4;
        num=0;
        if(sticks[0]>sum){   //剪枝2
            printf("no\n");
            continue;
        }
        memset(vis,0,sizeof(vis));
        if(dfs(0,0,0)){
            printf("yes\n");
        }
        else{
            printf("no\n");
        }
    }
    return 0;
}

参考博客:http://blog.csdn.net/lyy289065406/article/details/6647955

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值