POJ 2362 Square

来源:互联网 发布:金融数据挖掘python 编辑:程序博客网 时间:2024/06/06 06:32

** 题目地址:POJ 2362

  1. 题目大意:给n根长度不一的木棍,问是否能构成一个正方形

  2. 解题思路:由于题目限定4<=n<=20,可以直接用DFS,但是必须剪枝。首先可以很容易得到以下两个剪枝条件:
    a . 木棍总长度sum必须可以被4整除
    b . 最长的木棍的长度不得长于正方形边长
    根据这两个条件之后,如果可以拼凑出正方形的3条边,由于sum一定,那么就一定可以组成一个正方形,否则输出”no”.所以
    c . 深搜能得到正方形的三条边即可。**

#include<iostream>#include<algorithm>#include<string.h>#include<stdio.h>using namespace std;int n;//木棍个数bool visit[21];//是否被访问int stick[21];//木棍长度int side;//正方形边长bool cmp(int a,int b){    return a>b;}bool dfs(int num,int len,int root){//num为成功凑成的边数 //len为当前正在拼凑的边的长度 //root为起始访问的木棍数组的下标    if(num==3)        return true;    for(int i=root;i<n;i++)    {        if(visit[i])            continue;        visit[i]=true;        if(len+stick[i]<side)//若小于side        {            if(dfs(num,len+stick[i],i+1))//加上stick[i]产生新len,                return true;            //i+1可以避免没有意义的循环            //else visit[i]=false;            //若加上stick[i]后使得无法成功拼成正方形,则放弃当前边        }        else if(len+stick[i]==side)//若相等,则开始拼凑下一条边        {            if(dfs(num+1,0,0))                return true;            //else visit[i]=false;            //同上        }        visit[i]=false;//若大于side则暂时放弃当前边    }    return false;}int main(){    int t;    cin>>t;    while(t--)    {        cin>>n;int sum=0;        for(int i=0;i<n;i++)        {            cin>>stick[i];            sum+=stick[i];        }        sort(stick,stick+n,cmp);//先将木棍长度按照降序排列        side=sum/4;        memset(visit,false,sizeof(visit));        if(sum%4!=0||stick[0]>side)//剪枝1:总长度不能被4整除        {                          //剪枝2:最长木棍长于正方形边长            cout<<"no"<<endl;            continue;        }        if(dfs(0,0,0))            cout<<"yes"<<endl;        else            cout<<"no"<<endl;    }    return 0;}
1 0
原创粉丝点击