题目:

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. ACdream 1430——SETI——————【后缀数组,不重叠重复子串个数】

    SETI Time Limit: 4000/2000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Submit Statist ...

  2. 使用Pycharm开发python下django框架项目生成的文件解释

    目录MyDjangoProject下表示工程的全局配置,分别为setttings.py.urls.py和wsgi.py,1.其中setttings.py包括了系统的数据库配置.应用配置和其他配置,2. ...

  3. DBTransaction

    // Created by 张国锋 on 15-7-23. // Copyright (c) 2014年 张国锋. All rights reserved. // #import "AppD ...

  4. 给类型为text的input设置value值却无法修改

    给类型为text的input设置value值后就无法修改了 我的页面显示为如下但是退格却无法改变他的值 原来是缺少onChange事件,没法监听value的改变 所以需要添加 onChange={th ...

  5. Vue打包后页面出现cannot get

    学习Vue有大半个月了,然而遇到了不少坑,完全没有高手们那么容易,中间有不少值得记录下的东东,回头好好理理.先理下今天的: Vue打包命令简单啊,直接在命令行输入:npm run build 然而没一 ...

  6. 零基础逆向工程25_C++_02_类的成员权限_虚函数_模板

    1 类的成员权限 1.1 小结: 1.对外提供的函数或者变量,发布成public的 但不能随意改动. 2.可能会变动的函数或者变量,定义成private的 这样编译器会在使用的时候做检测. 3.只有结 ...

  7. MATLAB之折线图、柱状图、饼图以及常用绘图技巧

    MATLAB之折线图.柱状图.饼图以及常用绘图技巧 一.折线图 参考代码: %图1:各模式直接成本预测 %table0-table1为1*9的数组,记录关键数据 table0 = data_modol ...

  8. Objective-C 引用计数原理

    http://www.cocoachina.com/ios/20160112/14933.html 引用计数如何存储 有些对象如果支持使用 TaggedPointer,苹果会直接将其指针值作为引用计数 ...

  9. java基础编程——二维数组中的查找

    题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...

  10. C#的接口基础教程之七 覆盖虚接口

    有时候我们需要表达一种抽象的东西,它是一些东西的概括,但我们又不能真正的看到它成为一个实体在我们眼前出现,为此面向对象的编程语言便有了抽象类的概念.C#作为一个面向对象的语言,必然也会引入抽象类这一概 ...