DFS:HDU1518-Square(剪枝较多的DFS)
题目:
Square
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 15102 Accepted Submission(s): 4751
Problem Description
Given a set of sticks of various lengths, is it possible to join them end-to-end to form a square?
Input
The first line of input contains N, the number of test cases. Each test case begins with an integer 4 <= M <= 20, the number of sticks. M integers follow; each gives the length of a stick - an integer between 1 and 10,000.
Output
For each case, output a line containing "yes" if is is possible to form a square; otherwise output "no".
Sample Input
3
4 1 1 1 1
5 10 20 30 40 50
8 1 7 2 6 4 4 3 5
Sample Output
yes
no
yes
Source
University of Waterloo Local Contest 2002.09.21
解题心得:
1、一开始在看到这道题的时候真的很蒙蔽,不知道怎么递归,怎么判断是否可以拼成正方形,其实这道题只要利用正方形的性质就可以了,正方形有四条边并且四条边一样长,所以在递归的时候只需要递归拼成的边的长度和边的个数就行了,但是按照这种普通的思路会超时,这就很尴尬了,然后就剪枝呗。
2、这个题的剪枝比较复杂,给出的n小于4的直接剪去,给出的所有的和不是4的倍数的直接减去,最大的数超过了边长的直接减去,看似减得差不多了但是还是会超时,这里有一个小的技巧,在递归边长的时候是将几个数相加得到的边长,这个时候就可以先排一个序然后从小到大开始加,每一次递归的元素再加加在边长上排序好的那个数的位置就行了。
#include<bits/stdc++.h>
using namespace std;
int a[25];
bool flag,vis[25];
int n,ave; void dfs(int num,int len,int pos)//需要递归的元素以此是:边的条数,边的长度,加上的数的位置
{
if(num == 3 || flag)//由于之前预处理了,直接得到三条边就好,第四条边自动就出来了
{
flag = true;
return ;
}
if(len == ave)
{
dfs(num+1,0,0);
return;
}
for(int i=pos;i<n;i++)
{
if(!vis[i] && (len + a[i] <= ave))
{
vis[i] = true;
dfs(num,len+a[i],i+1);
vis[i] = false;
}
}
} int main()
{
int t;
int Max = -1;
int sum;
scanf("%d",&t);
while(t--)
{
memset(vis,0,sizeof(vis));
flag = false;
sum = 0;
Max = -1;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
sum += a[i];
}
sort(a,a+n);
if(n <= 3)//正方形有四条边
{
printf("no\n");
continue;
}
ave = sum /4;//平均每一条边的边长
if(sum % 4)//不是4的倍数的直接减去
{
printf("no\n");
continue;
}
if(a[n-1] > ave)//最大的一个数比平均边长还大的直接减去
{
printf("no\n");
continue;
}
dfs(0,0,0);
if(flag)
printf("yes\n");
else
printf("no\n");
}
}
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std; int n,cnt,sum; struct node
{
int lenth;
int mark;
}stick[25]; int cmp(node a,node b)
{
return a.lenth>b.lenth;
} int dfs(int len,int count,int l,int pos)
{
if(count==4)return 1;
for(int i=pos;i<n;i++)
{
if(stick[i].mark)continue; if(len==(stick[i].lenth+l))
{
stick[i].mark=1;
if(dfs(len,count+1,0,0))
return 1;
stick[i].mark=0;
return 0;
}
else if(len>(stick[i].lenth+l))
{
stick[i].mark=1;
l+=stick[i].lenth;
if(dfs(len,count,l,i+1))
return 1;
l-=stick[i].lenth;
stick[i].mark=0;
if(l==0) return 0;
while(stick[i].lenth==stick[i+1].lenth)i++;
}
}
return 0;
}
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%d",&n);
cnt=sum=0;
for(int i=0;i<n;i++)
{
scanf("%d",&stick[i].lenth);
sum+=stick[i].lenth;
stick[i].mark=0;
}
sort(stick,stick+n,cmp);
if(sum%4||n<4)
{
cout<<"no"<<endl;
continue;
}
cnt=sum/4;
if(dfs(cnt,0,0,0))
{
cout<<"yes"<<endl;
}
else
{
cout<<"no"<<endl;
}
}
return 0;
}
DFS:HDU1518-Square(剪枝较多的DFS)的更多相关文章
- HDU1518 Square(DFS,剪枝是关键呀)
Square Time Limit : 10000/5000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submi ...
- HDU1518 Square(DFS)
Square Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Su ...
- HDU1518 Square(DFS) 2016-07-24 15:08 49人阅读 评论(0) 收藏
Square Problem Description Given a set of sticks of various lengths, is it possible to join them end ...
- HDU-1518 Square(DFS)
Square Time Limit : 10000/5000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submi ...
- HDU1518:Square(DFS)
Square Time Limit : 10000/5000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submi ...
- HDU 1010 (DFS搜索+奇偶剪枝)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1010 题目大意:给定起点和终点,问刚好在t步时能否到达终点. 解题思路: 4个剪枝. ①dep&g ...
- poj 3373 Changing Digits (DFS + 记忆化剪枝+鸽巢原理思想)
http://poj.org/problem?id=3373 Changing Digits Time Limit: 3000MS Memory Limit: 65536K Total Submi ...
- UVA - 11882 Biggest Number(dfs+bfs+强剪枝)
题目大意:给出一个方格矩阵,矩阵中有数字0~9,任选一个格子为起点,将走过的数字连起来构成一个数,找出最大的那个数,每个格子只能走一次. 题目分析:DFS.剪枝方案:在当前的处境下,找出所有还能到达的 ...
- HDU 1010 Tempter of the Bone DFS(奇偶剪枝优化)
需要剪枝否则会超时,然后就是基本的深搜了 #include<cstdio> #include<stdio.h> #include<cstdlib> #include ...
随机推荐
- SpringBoot | 第二十一章:异步开发之异步调用
前言 上一章节,我们知道了如何进行异步请求的处理.除了异步请求,一般上我们用的比较多的应该是异步调用.通常在开发过程中,会遇到一个方法是和实际业务无关的,没有紧密性的.比如记录日志信息等业务.这个时候 ...
- 框架使用-Sql拼接
Sql语句拼写: 查询 DQueryDom DmoQuery(返回的整个对象) 更新 DQUpdateDom 删除 DQDeleteDom 条件 dom.Where.Conditions.Add(D ...
- 使用Foxfly.Net读取STEP文件
Foxfly.Net是具备基本的几何建模和CAD文件读取功能.本文主要介绍读取STP/STEP文件的使用方法. 1.初始化 项目中引入FoxflyNet.dll程序集,在Program.cs中初始化建 ...
- 移动端,点击a标签链接的pdf报错 Resource interpreted as Document but transferred with MIME type application/pdf
源码: <a href="11.pdf" class="actcont_a fl report_a" style="display: block ...
- valueOf() 和 toString()
valueOf():如果存在任意原始值,返回最适合该对象类型的原始值. toString():将该对象的原始值以字符串形式返回. 这两个方法一般是交由JS去隐式调用,以满足不同的运算情况. 举个栗子 ...
- COGS 1944. 背驮式行走
★ 输入文件:piggyback.in 输出文件:piggyback.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] Bessie和她妹妹Elsie白天都在牧场 ...
- Ruby 学习笔记(一)
环境搭建 本文基于Mac OS,windowns坑较多,建议使用Mac. xcode-select -p 检查是否安装xcode-select, 如果没有,通过xcode-select --insta ...
- NYOJ-22-素数求和问题
原题地址 素数求和问题 描述 现在给你N个数(0<N<1000),现在要求你写出一个程序,找出这N个数中的所有素数,并求和. 输入 第一行给出整数M(0<M<10)代表多少组测 ...
- WCF的问题
使用service调用WCF的时候,有时候会出现 其他信息: HTTP 无法注册 URL 进程不具有此命名空间的访问权限 这样的问题,这时候就需要进行如下尝试: 1,VS的管理权限使用管理员的权限. ...
- MYSQL短索引
优化MYSQL时,可以尽量使用短索引,如果只是为了提高读取的速度,可以优先使用聚合索引,把几个字段聚集在一起,当然缺点在于操作(写)的时候会降低效率,短索引一般都是开头几个字符基本不同的时候,可以考虑 ...