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;
    }

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

  • 相关阅读:
    Kafka 生产者 自定义分区策略
    同步互斥
    poj 1562 Oil Deposits(dfs)
    poj 2386 Lake Counting(dfs)
    poj 1915 KnightMoves(bfs)
    poj 1664 放苹果(dfs)
    poj 1543 Perfect Cubes (暴搜)
    poj 1166 The Clocks (暴搜)
    poj 3126 Prime Path(bfs)
    处理机调度
  • 原文地址:https://www.cnblogs.com/sy666/p/12722601.html
Copyright © 2011-2022 走看看