poj 2362 hdoj 1518 Square(搜索)

简介: 不难了解,小棒子的长度越长,其灵活性越差。例如长度为5的一根棒子的组合方式要比5根长度为1的棒子的组合方式少,这就是灵活性的体现。

题目链接


大致题意:


给定一堆不定长度的小棒子,问他们能否构成一个正方形。



解题思路:


POJ1011的热身题,DFS+剪枝



本题大致做法就是对所有小棒子长度求和sum,sum就是正方形的周长,sum/4就是边长side。


问题就转变为:这堆小棒子能否刚好组合成为4根长度均为side的大棒子



不难了解,小棒子的长度越长,其灵活性越差。例如长度为5的一根棒子的组合方式要比5根长度为1的棒子的组合方式少,这就是灵活性的体现。


由此,我们首先要对这堆小棒子降序排序,从最长的棒子开始进行DFS



剪枝,有3处可剪:


1、  要组合为正方形,必须满足sum%4==0;


2、  所有小棒子中最长的一根,必须满足Max_length <= side,这是因为小棒子不能折断;


3、  当满足条件1、2时,只需要能组合3条边,就能确定这堆棒子可以组合为正方形。

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
bool vis[21];
int stick[21];
int n;
int side;
bool cmp(int a, int b)
{
    return a > b;
}
bool dfs(int num, int len, int s)//s为搜索起点
{
    if (num == 4)
        return true;
    for (int i = s; i < n; i++)
    {
        if (vis[i])
            continue;
        vis[i] = true;
        if (len+stick[i] < side)
        {
            if (dfs(num, len+stick[i], i))
            //这里解释游戏为什么有搜索起点这一变量,只有这用到了,如果len+stick[i] > side了
            //因为是非升序,len+stick[i-1] > side必然成立,从0开始就是浪费时间
                return true;
            /*开始这里我直接 return dfs(num, len+stick[i], i);貌似这样也可以,
            但的的确确是错的,直接返回会导致我们少判很多种情况*/
        }
        else if (len+stick[i] == side)
        {
            if (dfs(num+1, 0, 0))
                return true;
            //这里同上
        }
        vis[i] = false;
    }
    return  false;
}
int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d", &n);
        int sum = 0;
        for (int i = 0; i < n; i++)
        {
            scanf("%d", &stick[i]);
            sum += stick[i];
        }
        side = sum/4;
        sort(stick, stick+n, cmp);
        if (sum % 4 || side < stick[0])
        //这里也可以去掉一些情况
        {
            puts("no");
            continue;
        }
        memset(vis, false, sizeof(vis));
        if (dfs(1, 0, 0))
            puts("yes");
        else
            puts("no");
    }
    return 0;
}
目录
相关文章
|
4月前
|
索引
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
40 0
Leetcode第三十三题(搜索旋转排序数组)
|
8月前
|
机器学习/深度学习 算法 数据挖掘
LeetCode题目74:搜索二维矩阵
LeetCode题目74:搜索二维矩阵
|
9月前
|
算法 测试技术 C#
【二分查找】【z型搜索】LeetCode240:搜索二维矩阵
【二分查找】【z型搜索】LeetCode240:搜索二维矩阵
|
机器学习/深度学习 算法 测试技术
LeetCode:搜索二维矩阵题解
请写出一个高效的在m*n矩阵中判断目标值是否存在的算法,矩阵具有如下特征: 每一行的数字都从左到右排序 每一行的第一个数字都比上一行最后一个数字大
134 0
|
算法 安全 Swift
LeetCode - #33 搜索旋转排序数组(Top 100)
不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。
|
算法
【PTA】168(搜索 + 找规律)
【PTA】168(搜索 + 找规律)
170 0
【PTA】168(搜索 + 找规律)
|
并行计算
POJ - 3984 迷宫问题 (搜索)
Problem Description 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
1486 0

热门文章

最新文章