POJ 2362:Square 觉得这才算深度搜索

Square

Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 21821   Accepted: 7624

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

这个题和POJ1011觉得真的是两道特别棒的题目,仔细琢磨很有味道。这个题一开始输出大写的YES和NO导致WA了一次。。。

题意是给你M根木棒,接下来给你每根木棒的长度,问这些木棒是否能够构成一个正方形。

具体理解见代码:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#pragma warning(disable:4996)
using namespace std;

int num_s,flag,sum;
int stick[25];
bool visit[25];

bool dfs(int num,int length,int stick_st,int * stick,bool *visit)
{
	if(num==4)
		return true;
	int i;
	for(i=stick_st;i<=num_s;i++)
	{
		if(visit[i])continue;

		visit[i]=true;
		if(length+stick[i]<(sum/4))
		{
			if(dfs(num,length+stick[i],i+1,stick,visit))
			{
				return true;
			}
		}
		else if(length+stick[i]==(sum/4))
		{
			if(dfs(num+1,0,1,stick,visit))
			{
				return true;
			}
		}
		visit[i]=false;
	}
	return false;
}

bool cmp(const int a,const int b)
{
	return a>b;
}

int main()
{
	int Test,i;
	cin>>Test;

	while(Test--)
	{
		cin>>num_s;
		sum=0;
		flag=0;
		for(i=1;i<=num_s;i++)
		{
			cin>>stick[i];
			visit[i]=false;
			sum += stick[i];
		}
		if(num_s<4||sum%4)//剪枝1:如果木棒数量小于4,cut。
		                  //剪枝2:如果sum的和不能整除4,cut。
		{
			cout<<"no"<<endl;
		}
		else
		{
			sort(stick+1,stick+1+num_s,cmp);
			if(stick[1]>sum/4)//剪枝3:如果最大的一根木棒大于了sum/4,cut。
				cout<<"no"<<endl;
			else
			{
				if(dfs(1,0,1,stick,visit))//第一个数代表当前要完成的第几根木棒
				                          //第二个数代表当前已经完成的长度
				                          //第三个数代表从第几个木棒开始查找的
				{
					cout<<"yes"<<endl;
				}
				else
				{
					cout<<"no"<<endl;
				}
			}
		}
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 18:54:55

POJ 2362:Square 觉得这才算深度搜索的相关文章

DFS POJ 2362 Square

题目传送门 1 /* 2 DFS:问能否用小棍子组成一个正方形 3 剪枝有3:长的不灵活,先考虑:若根本构不成正方形,直接no:若第一根比边长长,no 4 这题是POJ_1011的精简版:) 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <cstring> 9 #include <map> 10 #include <set> 11 #include <cmath>

POJ 2362 Square

题意:给n个木棍,问能不能正好拼成一个正方形. 解法:POJ1011的简单版……不需要太多剪枝……随便剪一剪就好了……但是各种写屎来着QAQ 代码: #include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include&

POJ 2362:Square(DFS)

问所给木棒能否构成一个正方形 难点在于木棒可以拼接,比如2 2 1 1 2也是能构成正方形的 这题的剪枝有点意思: 第一是提前判断所给的木棒长度之和能否被4整除,不能直接输出NO 第二是只需满足上面的条件后,只需要找到3条边就行了,剩下一条边自然也符合 l表示已找到的长度,cnt为已找到的边 #include"cstdio" #include"cmath" #include"cstring" #include"algorithm&quo

怎样才算会一门编程语言(如果你已经会了一门语言, 并且想一直会这门语言, 请在工作持续使用。如果没有机会使用, 自己给自己创造机会)

今天, 同事问我会不会Python, 我犹豫了一下:不会. 实际上我曾经学习过这个语言,当时还用它写了些小工具, 可现在我对这个语言的印象只剩下它那特殊的缩进格式了. 由此思考怎样才算会一门语言?我想每个程序员都接触过多门语言 , 那么究竟怎样才算会这门语言了呢? 会一门语言, 当需要它时, 应该能很快用该语言解决某个问题, 这个是最基本的. 如果深入一点, 真正会一门语言, 我觉得需要满足以下几点: a. 有超过一年的实践经验 b. 理解语言背后的机制, 最好阅读过该语言标准库的部分源码 c.

什么时候懂得了拒绝,才算真正长大了

学会拒绝,是人长大后要具备的第一能力.或者,换一种说法就是:什么时候懂得了拒绝,才算真正长大了. 施予,是帮助他人.拒绝,是保护自己.在帮助他人之前,先学会保护自己,我觉得一点错也没有.合格的崇高是:能站在道德的高度上做事,却始终不被道德绑架. 一个人,适当行使拒绝权,是有立场和有态度的体现.在这个世俗社会,好说话,别人未必把你当回事.恰恰是,他人在你这里碰钉子,反而会赢得敬畏和尊重. 没有拒绝的人,是不会有原则性的.就像没有坚守的人,绝难有原则性一样.于人生来说,学会拒绝与懂得坚守一样重要.有

POJ 2362

知识点:dfs(深度优先搜索) 题解:基本的dfs搜索判断可行性问题.一般的dfs搜索,如果不加剪枝,复杂度是指数级的,所以必须要能发掘出优秀的剪枝条件: 在本题中,一般有如下剪枝: ①:所有线段的长度之和必须为4的倍数:②:搜索之前,把所有线段按从大到小排序,因为长度越长,在拼凑时的灵活度就越低:③:当能拼凑出3根等长的线段时,第四根就无须再搜了:④:当用某一条线段无法得出可行解时,和它等长的,一样不可以: 有了以上四个剪枝条件,这题就可以过了: add:这题理解之后可以去看看poj 1011

hdu--1978--记忆化深度搜索||递推

这题 我开始的做法是 记忆化搜索  但是tm地竟然tle了...很想不通 因为数据很小啊 就100 虽然方案的总数可能会很大.. 然后 我就去百度 记忆化搜索 看下是不是我用错方法了 事实证明 我虽然没有用错 但还是 学到了很多=-=. 其实  我很早以前 也看过关于 记忆化搜索的一些介绍 但是 并没有太多感觉 并不是那些作者写的不好 而是我的水平没到 感受不了.. 很多东西会在不知不觉中提升~ 我想 将我读的这篇介绍 传到这篇博客里来 似乎只能上传照片和视频=-=   那我给个链接吧  传送

深度搜索入门

深度优先搜索是搜索的手段之一.它从某个状态开始,不断地转移状态,直到无法转移,然后回退到前一步的状态,继续转移到其他状态,如此重复,直到找到最终的解. 做这类题目,抓住两样东西:1.总体上递归几次(几层)?每一次递归确定一层上的数. 2.每次递归,有几种选择的情况.所以dfs()函数,只有两部分(if.else结构):1.(if部分)若每一层都选择了,判断是否符合条件,做出题目要求的操作.2.(else部分)若还有层没有选择,就做出选择,所有选择的情况列出. 下面是几个考察dfs的题目: 1.部

POJ 2704 Pascal&#39;s Travels (基础记忆化搜索)

Pascal's Travels Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5328   Accepted: 2396 Description An n x n game board is populated with integers, one nonnegative integer per square. The goal is to travel along any legitimate path from t