首页 > 其他 > 详细

洛谷P2383 狗哥玩木棒

时间:2020-04-17 23:34:10      阅读:105      评论:0      收藏:0      [点我收藏+]

题目链接: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\n");
        else printf("no\n");
    }
    return 0;
}

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

洛谷P2383 狗哥玩木棒

原文:https://www.cnblogs.com/sy666/p/12722601.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!