zoukankan      html  css  js  c++  java
  • 洛谷P2383 狗哥玩木棒

    题目链接:https://www.luogu.com.cn/problem/P2383

    这道题是一个搜索题,m<=20,合理的剪枝应该能过

    有几个剪枝方法:

        1.将数据从大到小排序在搜索。

        2.如果拼好了就返回。

        3.记录边长度和add,若搜索时又一边超过add/4就返回。

    代码:

    #include<stdio.h>
    int m,n,a[21],add,flag,q;
    void px(int k,int s){//排序 
        int i,j,mid,p;
        i=k;j=s;
        mid=a[(k+s)/2];
        do{
            while(a[i]>mid)i++;
            while(a[j]<mid)j--;
            if(i<=j){
                p=a[i];a[i]=a[j];a[j]=p;
                i++;j--;
            }
        }while(i<=j);
        if(k<j)px(k,j);
        if(i<s)px(i,s);
        return;
    }
    void dfs(int a1,int a2,int a3,int a4,int k){//四条边a1,a2,a3,a4,搜索到第k条木棒
        if(flag)return;//剪枝2
        if(a1>q||a2>q||a3>q||a4>q)return;//剪枝3
        if(k==m+1&&a1==q&&a2==q&&a3==q&&a4==q){flag=1;return;}
        if(k==m+1)return;
        dfs(a1+a[k],a2,a3,a4,k+1);//分别给4条边加木棍长度
        dfs(a1,a2+a[k],a3,a4,k+1);
        dfs(a1,a2,a3+a[k],a4,k+1);
        dfs(a1,a2,a3,a4+a[k],k+1);
        return;
    }
    int main(){
        scanf("%d",&n);
        for(int h=1;h<=n;h++){
            scanf("%d",&m);
            for(int i=1;i<=m;i++)scanf("%d",a+i);
            add=0;
            for(int i=1;i<=m;i++)add+=a[i];
            q=add/4;
            px(1,m);//排序 剪枝1
            flag=0;
            dfs(0,0,0,0,1);
            if(flag)printf("yes
    ");
            else printf("no
    ");
        }
        return 0;
    }

    我可能写的不好,如果有问题,请帮忙指出,谢谢。

  • 相关阅读:
    poj3468(A Simple Problem with Integers)线段树+树状数组
    关于JVM——JVM内存模型
    关于JVM——类加载机制
    关于JVM(二)
    关于JVM(一)
    关于LongAdder
    关于Future
    关于Fork/Join
    关于Atomic
    关于LockSupport
  • 原文地址:https://www.cnblogs.com/sy666/p/12722601.html
Copyright © 2011-2022 走看看