题目:

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. redis安装及简单命令

    Redis 安装 Window 下安装 下载地址:https://github.com/MSOpenTech/redis/releases. Redis 支持 32 位和 64 位.这个需要根据你系统 ...

  2. Windbg .net内存调试有用的命令(笔记 )

    和.net内存调试相关的Windbg命令 首先.load sosex.dll加载ex调试扩展dll 1.!gcgen [obj地址] 显示对象属于gc代数 2.!dumpgen [0/1/2] dum ...

  3. 一、 Spring IOC 简介

    一 . 什么是IOC(Inversion of Control) IOC :控制反转,也称为依赖注入(DI).听起来有点云里雾里,他到底是个啥,为什么Spirng中最基础的就是它? 我们的项目其实都是 ...

  4. mysql set names 命令和 mysql字符编码问题

    先看下面的执行结果: (root@localhost)[(none)]mysql>show variables like 'character%'; +--------------------- ...

  5. 日常bug整理--xxtz

    2017-12-12 建SQLite数据库表时,遇到外键关联报错:foreign key mismatch 解决:发现是个粗心问题,关联的外键没有作为主键,原因是关联的外键由INT改为varchar字 ...

  6. LESS CSS非常实用实例应用

    @charset "UTF-8"; @base-color:#333; // 圆角 .border-radius (@radius: 5px) { -webkit-border-r ...

  7. css 03

    DIV+CSS盒子模型 一.盒子模型css height width padding 内边距 margin  外边距 border 1.margin 外边距 margin-top:15px; marg ...

  8. 编程中的多字节和Unicode

    在编译许多程序的时候,我们常常会出现诸如指针转换错误或者const char[] 不能转换成XX的错误,这时很可能就是项目编码的问题了,如果您使用的是VS编程环境,那么打开工程属性,里面就有个选项是给 ...

  9. SpringBoot集成mybatis和mybatis generator

    利用搭建的基本的spring boot框架,集成 mybatis + generator 1.设置 maven 的相关配置: File  - setting - maven 设置 Maven home ...

  10. 彻底解决Android 应用方法数不能超过65K的问题

    作为一名Android开发者,相信你对Android方法数不能超过65K的限制应该有所耳闻,随着应用程序功能不断的丰富,总有一天你会遇到一个异常: Conversion to Dalvik forma ...