Square HDU 1518 搜索
Square HDU 1518 搜索
题意
给你一定若干个木棒,让你使用它们组成一个四边形,要求这些木棒必须全部使用。
解题思路
木棒有多种组合方式,使用搜索来进行寻找,这里需要进行优化,不然复杂度非常高。
因为M最大为20,所以,如果用DFS还是可以接受的。
由所有火柴棒的长度和,我们可以求出要组成正方形的边长。我们设边长为len。在搜索前,首先可以把边长为分数的,也就是火柴棒的长度和不能被4整除的,排除掉。
问题可以转化为从M个数中挑出4组和为len的数。
首先,从M个数中搜索出和为len的数。如果能搜到,则接着从剩余的数中,进行同样的搜索,依此类推,一共进行4段这样的搜索。
如果某一段搜索失败,则回溯到上一段搜索。
如果一直回溯到第一段的搜索,仍未能找到解,则说明无解。
搜索过程
将长度按从大到小排序。
对应正方形的4条边,进行4段同样的搜索。而且这4段搜索也是递归式的,就是说,当第一段边搜索到后,便递归进行下一段的搜索。由此可见,搜索过程中要用到的信息包括:当前是第几段;当前段还剩余的长度;搜索的起始位置。
每段搜索的过程是相同的:因为到最后,所有的火柴棒都是会被用到的,所以,每当开始一个新段的搜索时,总是把剩余的第一个数放入,在这段的搜索过程中,它始终是放入状态。然后进入堆栈的下一层,试着放入下一个剩余的数,如果放入这个数后递归到下面未回溯回来,则说明已经找到最后答案,程序结束。如果得到回溯,那么把该数取出,同理再试着放入排在它后面的数。
搜索的起始位置
起始位置就是,在每次进入递归函数的时候,应该从哪个位置的数开始试着放入;如果这次递归要放入的是一个段的第一个数,这个数肯定是剩余的第一个数,而且这个数是不会被取出的,也就是说,这一层的可选状态只有一个,如果放入这个数之后,后面发现无法搜索到一个完整的边,那么说明剩余的数到达最终的目标,必须回溯到上一个段。
如果这次递归要放入不是一个段的第一个数,那么它的起始位置肯定是在它上一层递归放入的数的后面,但是它前面可能还存在没有被放入的数,这些数就不用再试了吗?
因为是对同一个段的搜索,所以,组成这个段的数被放入的顺序是没有关系的。所以,如果一个数作为一个段的第一个数放入不合适,那么它作为第二个数或第三个数放入肯定也是不合适的。
代码实现
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e4+7;
int a[maxn], vis[maxn], sum;
int m, len;
bool dfs(int duan, int begin, int left)//记录当前的段数,数组的位置,当前段还需要多长的木棍
{
if(left==0)
{
if(duan==3) return 1;
int i;
for( i=1; i<=m && vis[i]!=0; i++);
vis[i]=1;
if(dfs(duan+1, i, len-a[i])) return 1;
vis[i]=0;
return 0;
}
for(int i=begin; i<=m; i++)
{
if(vis[i]==1 || a[i] > left) continue;
if(i>1 && vis[i-1]==0 && a[i-1]==a[i]) continue;
vis[i]=1;
if(dfs(duan, i, left-a[i])) return 1;
vis[i]=0;
}
return 0;
}
bool cmp(int a, int b)
{
return a>b;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d", &m);
sum=0;
for(int i=1; i<=m; i++)
{
scanf("%d", &a[i]);
sum+=a[i];
vis[i]=0;
}
if(sum%4!=0)
{
printf("no\n");
continue;
}
sort(a+1, a+1+m, cmp);
len=sum/4;
if(a[1] > len)
{
printf("no\n");
continue;
}
vis[1]=1;
if( dfs(1, 1, len-a[1]) )
printf("yes\n");
else printf("no\n");
}
return 0;
}
Square HDU 1518 搜索的更多相关文章
- hdu 5887 搜索+剪枝
Herbs Gathering Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- hdu 5636 搜索 BestCoder Round #74 (div.2)
Shortest Path Accepts: 40 Submissions: 610 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: ...
- HDU 1518 Square 搜索
Problem Description Given a set of sticks of various lengths, is it possible to join them end-to-end ...
- 杭电1518 Square(构成正方形) 搜索
HDOJ1518 Square Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- hdu 1518 Square(深搜+剪枝)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1518 题目大意:根据题目所给的几条边,来判断是否能构成正方形,一个很好的深搜应用,注意剪枝,以防超时! ...
- hdu 1518 Square 深搜,,,,花样剪枝啊!!!
Square Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Su ...
- hdu 1518 Square 木棍建正方形【DFS】
题目链接 题目大意: 题意就是输入棍子的数量和每根棍子的长度,看能不能拼成正方形. #include <bits/stdc++.h> using namespace std; int n, ...
- HDU 1518 Square(DFS)
Problem Description Given a set of sticks of various lengths, is it possible to join them end-to-end ...
- HDU 1518 Square
解题思路:sum%4!=0 , max<sum/4 #include<iostream>#include<cstdio>#include<cstring> ...
随机推荐
- SpringApplication.run 做了哪些事?
SpringApplication.run一共做了两件事,分别是 创建SpringApplication对象 利用创建好的SpringApplication对象,调用run方法论 结论: 面试官: 我 ...
- linux 内存
[转]Linux 查看内存(free buffer cache) 转自:http://elf8848.iteye.com/blog/1995638 Linux下如何查内存信息,如内存总量.已使用量.可 ...
- html body标签 语法
html body标签 语法 标签body是什么意思? 标签body是一个网页的身体部分,也就是用于定义网页的主体内容,也是一个HTML文档中必须的部分. 作用:定义文档的主体. 广州大理石机械构件 ...
- MongoDB操作:insert()
@Override public boolean inSert(String dbName, String collectionName, String[] keys, Object[] values ...
- luoguP1197 [JSOI2008]星球大战 x
P1197 [JSOI2008]星球大战 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中 ...
- nginx展示文件目录
1. 如何让nginx显示文件夹目录 vi /etc/nginx/conf.d/default.conf 添加如下内容: location / { root /data/www/file //指定实际 ...
- 论文阅读:Stateless Network Functions: Breaking the Tight Coupling of State and Processing
摘要: 无状态网络功能是一个新的网络功能虚拟化架构,解耦了现有的网络功能设计到无状态处理组件以及数据存储层,在打破紧密耦合的同时,实现了更具可伸缩性和可恢复性的网络功能基础设施.无状态NF处理实例是围 ...
- Min_25筛初级应用:求$[1,n]$内质数个数
代码 #include <bits/stdc++.h> #define rin(i,a,b) for(int i=(a);i<=(b);++i) #define irin(i,a,b ...
- DVWA--XSS(反射型)
0X01爱之初介绍 虽然XSS已经做了两节了 但是还是还是简单解释一下 前言:跨站脚本(Cross-Site Scripting,XSS)是一种经常出现在Web应用程序中的计算机安全漏洞,是由于Web ...
- 读读《编写高质量代码:改善Java程序的151条建议》
这本书可以作为平时写代码的一个参考书,这本书以我个人读的经验看来,最好是通过平时代码驱动的方式来读,这样吸收的快,也读的快. 这本书主要讲什么,我自己用了个思维导图概述: 根据这种导图可知,主要讲的就 ...