zoukankan      html  css  js  c++  java
  • dfs+剪枝:poj2362

    贴题目

    Square
    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 24604   Accepted: 8449

    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".
     
    一道和1011很像的剪枝,在做了1011之后我写了这道题,结果不幸的wa了。所以说,1011的测点很水QAQ
    读题后发现以下剪枝:
    1、如果所有木棍和加起来不能被4整除,那么不能构成square;
    2、将所有木棍和除以4的值(边长)保存,如果子段中的最大长度大于这一值,那么不能构成square;
    3、与1011同理,同一长度的木棍不需重复判断;
    4、将木棍从大到小开始找,因为越小的木棍灵活度越高。
    分析可知,如果已经构成了3条边符合要求,那么一定能构成一个正方形。所以在进行第四边查找时,我们可以直接确定可以构成正方形。
    代码如下:
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    bool flag,zt[25];
    int n,m,a[25],sum,l,mm,i;
    using namespace std;
    bool cmp(const int a,const int b){
        return a>b;
    }
    void dfs(int num,int len,int now){
        if(flag)return ;
        if(num==4){
            flag=true;
            return;
        }
        if(len==sum){
            dfs(num+1,0,1);
            if(flag)return ;
        }
        int i;
        for(i = now; i <= mm ; ++i){
            if(!zt[i]&&len+a[i]<=sum){
                zt[i]=true;
                dfs(num,len+a[i],i+1);
                zt[i]=false;
                if(flag)return ;
            }
        }
        return ;
    }
    void start(){
        sum=0;
        memset(a,0,sizeof(a));
        flag=false;
        i=0;
    }
    int main(){
        scanf("%d",&n);
        while(n--){
            start();
            scanf("%d",&m);
             mm=m;
            while(m--){
                ++i;
                scanf("%d",&a[i]),sum+=a[i];
            }
            sort(a+1,a+mm+1,cmp);
            if(sum%4||a[1]>sum){
                printf("no
    ");
                continue;
            }
            sum/=4;
            memset(zt,0,sizeof(zt));
            dfs(0,0,1);
            if(flag)printf("yes
    ");    
            else printf("no
    ");
        }
        return 0;
    }
    dfs的习题重要的就是剪枝,拿到题目一定要多分析,尽可能多地找出不必要的枝,来提高时间效率。博主自己还要注意的就是细心,总是出一些没有必要的小毛病,希望能改掉这个毛病。
    今天写的比较匆忙,不足的地方麻烦大家帮我提出来了~嗯,以后还是要加强练习。
  • 相关阅读:
    多输出感知机及其梯度
    《机器学习实战》-线性回归
    《机器学习实战》-逻辑(Logistic)回归
    SQL Server 空间监测
    SQL Server 从数据库快照还原数据库
    SQL Server 创建数据库快照
    SQL Server 数据库的自动选项
    SQL Server 数据库游标选项
    SQL Server 数据库状态选项
    MYSQL 二进制还原
  • 原文地址:https://www.cnblogs.com/fujudge/p/6812893.html
Copyright © 2011-2022 走看看