题目:

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的倍数的直接减去,最大的数超过了边长的直接减去,看似减得差不多了但是还是会超时,这里有一个小的技巧,在递归边长的时候是将几个数相加得到的边长,这个时候就可以先排一个序然后从小到大开始加,每一次递归的元素再加加在边长上排序好的那个数的位置就行了。


我的代码:776ms
#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");
}
}




大神的代码:4ms
#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)的更多相关文章

  1. HDU1518 Square(DFS,剪枝是关键呀)

    Square Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submi ...

  2. HDU1518 Square(DFS)

    Square Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Su ...

  3. 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 ...

  4. HDU-1518 Square(DFS)

    Square Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submi ...

  5. HDU1518:Square(DFS)

    Square Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submi ...

  6. HDU 1010 (DFS搜索+奇偶剪枝)

    题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=1010 题目大意:给定起点和终点,问刚好在t步时能否到达终点. 解题思路: 4个剪枝. ①dep&g ...

  7. poj 3373 Changing Digits (DFS + 记忆化剪枝+鸽巢原理思想)

    http://poj.org/problem?id=3373 Changing Digits Time Limit: 3000MS   Memory Limit: 65536K Total Submi ...

  8. UVA - 11882 Biggest Number(dfs+bfs+强剪枝)

    题目大意:给出一个方格矩阵,矩阵中有数字0~9,任选一个格子为起点,将走过的数字连起来构成一个数,找出最大的那个数,每个格子只能走一次. 题目分析:DFS.剪枝方案:在当前的处境下,找出所有还能到达的 ...

  9. HDU 1010 Tempter of the Bone DFS(奇偶剪枝优化)

    需要剪枝否则会超时,然后就是基本的深搜了 #include<cstdio> #include<stdio.h> #include<cstdlib> #include ...

随机推荐

  1. PHPGGC学习----实践

    本文首发于先知:https://xz.aliyun.com/t/5450 PHPGGC学习----理论部分对PHPGGC工具的使用方法有了一个基本的了解,接下来需要利用实践环境进行一个实践操作,巩固一 ...

  2. ASP.NET MVC缓存

    根据缓存的位置不同,可以区分为: ①客户端缓存(缓存在用户的客户端,例如浏览器中) ②服务器缓存(缓存在服务器中,可以缓存在内存中,也可以缓存在文件里,并且还可以进一步地区分为本地缓存和分布式缓存两种 ...

  3. java递归展示树形图代码实现以及遇到的问题

    我最近写到了一个项目中用到了树形图,不得不说这个树形图是真的扯淡: 我用到的是layui中的树形图,再展示数据过程中遇到了很多的问题,废话不多说,直接贴代码. 一.调用排序接口,对数据进行排序. 二. ...

  4. jstack的使用方法

    背景 记得前段时间,同事说他们测试环境的服务器cpu使用率一直处于100%,本地又没有什么接口调用,为什么会这样?cpu使用率居高不下,自然是有某些线程一直占用着cpu资源,那又如何查看占用cpu较高 ...

  5. CSS文档优化

    首先了解下CSS的渲染逻辑,它是从标记的最后一位开始搜索的,例如:.myclass li a,首选它会遍历所有的<a>,然后看哪些<a>之前有<li>,然后再看哪些 ...

  6. Remote System Explorer Operation在eclipse后台一直跑 解决办法

    在用eclipse开发时,经常遇到卡死的情况,其中一种就是右下角出现:“Remote System Explorer Operation”,解决方案如下: 第一步:Eclipse -> Pref ...

  7. Navicat for Oracle设置唯一性和递增序列

    [数据库] Navicat for Oracle基本用法图文介绍 一. 设置唯一性 参考文章:Oracle之唯一性约束(UNIQUE Constraint)用法详解唯一性约束英文是Unique Con ...

  8. Echarts图表学习

    最近项目已经运行的比较稳定了,正巧看到ECcharts的图标很炫,遂做一个玩玩,以备后面做数据分析使用. 官网地址:http://echarts.baidu.com/index.html 大致了解了下 ...

  9. TestNG并发测试包

    https://www.yiibai.com/testng/basic-annotations.html

  10. Android商城开发系列(十)—— 首页活动广告布局实现

    在上一篇博客当中,我们讲了频道布局的实现,接下来我们讲解一下活动广告布局的实现,效果如下图: 这个是用viewpager去实现的,新建一个act_item.xml,代码如下所示: <?xml v ...