【DFS+剪枝】-HDU-1518-Squares

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1518

题目描述:给出若干个破木头条子。问你它们能否拼成一个正方形。

解题思路:

一道DFS题,DFS是我软肋啊。不过经过这道题,算是找到一种固定模式了,以后遇到DFS题就不会不知♂所措。

解释一下我DFS函数中的变量 len 和 dep,分别表示手里拿的木棍总长,每当达到一个边长就放下这些木棍(并标记),再从头开始找,dep表示已找到的边长数量,显然找到 4 个就能构成正方形。

交上去T了。

所以我们再考虑剪枝,问题出在我写的基本上是一个生成全排列的DFS,而这道题显然不用考虑顺序,所以每次不用从 1 开始搜,加入一个 from 变量记一下位置,下次接着搜就好了,也就是说 “排列” 和 “组合” 是不同的。这样就AC了。

我还在想,那是不是不需要 use 数组了,去掉是 WA 的,因为在你凑齐一个边长并放下手里木棍时候必须标记好用过哪些,再找的时候才是对的。

AC代码:

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

int arr[30],use[30];
int num,sum,found;

void dfs(int from,int len,int dep)
{
    if(!found&&len<=sum/4)
    {
        //cout<<len<<" "<<dep<<endl;
        int i;
        if(len==sum/4)
        {
            if(dep==4)
                found=1;
            else
                dfs(1,0,dep+1);
        }
        else
        {
            for(i=from;i<=num;i++)
            {
                if(!use[i])
                {
                    use[i]=1;
                    dfs(i+1,len+arr[i],dep);
                    use[i]=0; 
                }
            }
        }
    }
}

int main()
{
    //freopen("1518_input.txt","r",stdin);
    int T,i;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&num);
        sum=0;found=0;
        memset(arr,0,sizeof(arr));
        memset(use,0,sizeof(use));
        for(i=1;i<=num;i++)
        {
            scanf("%d",&arr[i]);
            sum+=arr[i];
        }
        if(sum%4!=0)
        {
            printf("no\n");
        }
        else
        {
            dfs(1,0,1);
            if(found)
                printf("yes\n");
            else
                printf("no\n");
        }
    }

    return 0;
}
AC截图:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值