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 ...
随机推荐
- xenserver 更新源
在xenserver上安装vnc软件时,报错 [root@cloud yum-3.4.3]# ./yummain.py install yumThere are no enabled repos.Ru ...
- <probing> 元素指定扩展Asp.Net加载程序集位置
下面的示例说明如何指定运行库应在其中搜索程序集的应用程序基子目录. <configuration> <runtime> <assemblyBinding xmln ...
- Java基础反射-调用类
Student类 package com.test.wang; import java.lang.reflect.Constructor; import java.lang.reflect.Field ...
- flask之jinja2模板语言
一.jinja2简单介绍 Jinja2是Python里一个被广泛应用的模版引擎,他的设计思想来源于Django的模板引擎,并扩展了其语法和一系列强大的功能.其中最显著的一个是增加了沙箱执行功能和可选的 ...
- c语言数据结构:用标志位实现循环队列
#include<stdio.h> #include<stdlib.h> #define MAXSIZE 10//定义队列长度 ;//定义标志位 typedef struct ...
- 解决windows7系统的快捷方式无法添加到任务栏
#以下4条,进入cmd命令界面下逐个执行cmd /k reg add "HKEY_CLASSES_ROOT\lnkfile" /v IsShortcut /fcmd /k reg ...
- jenkins代码自动部署
jenkins是一个广泛用于持续构建的可视化web工具,持续构建说得更直白点,就是各种项目的"自动化"编译.打包.分发部署.jenkins可以很好的支持各种语言(比如:java, ...
- 详细步骤教你安装yii高级应用程序和配置composer环境
现在开始工作,应公司的要求,要开始接触yii了,作为一个没有碰过yii的小白,首先一个问题就是怎么去安装高级程序应用,过程不麻烦,但是也需要细心和耐心,百度资料里面的教程都不太全,漏这漏那的,所以在这 ...
- pta 编程题16 Saving James Bond - Easy Version
其它pta数据结构编程题请参见:pta 题目 主要用到了深度优先搜索. #include <iostream> using namespace std; struct Vertex { i ...
- codeforces 600C Make Palindrome
要保证变化次数最少就是出现次数为奇数的相互转化,而且对应字母只改变一次.保证字典序小就是字典序大的字母变成字典序小的字母. 长度n为偶数时候,次数为奇数的有偶数个,按照上面说的搞就好了. n为奇数时, ...