码迷,mamicode.com
首页 > 其他好文 > 详细

DFS——hdu1518Square

时间:2017-08-07 20:38:39      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:i++   const   form   and   tin   square   between   回顾   put   

一、题目回顾

题目链接:Square

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
 
二、解题思路
  • DFS
  • 剪枝

 

三、代码

//dfs+剪枝 
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 1e4+10;
#define INF 0x3f3f3f3f
int a[maxn];
int n,m,ave;						//边长 
bool vis[maxn];
bool flag;

void dfs(int num,int len,int start)		//已凑完的边数,当前这条边的长度,从第几根木棍开始找 
{
	 if(num==4){
	 	flag = 1;
	 	return;						//有4条边时,即可返回 
	 }
	 if(len==ave){
	 	dfs(num+1,0,0);
	 	if(flag)
	 		return;
	 }
	 for(int i=start;i<m;i++){
	 	if(!vis[i] && a[i]+len<=ave){
	 		vis[i] = 1;
	 		dfs(num,a[i]+len,i+1);
	 		if(flag)	return;
	 		vis[i] = 0;					//剪枝,即第i个棍子加入不能形成正方形就不选此棍子 
	 	}
	 }	
}

int main()
{
	cin>>n;
	while(n--){
		cin>>m;
		int sum=0, maxlen=0;
		for(int i=0;i<m;i++){
			scanf("%d",&a[i]);
			sum += a[i];
			if(a[i]>maxlen)		maxlen = a[i];
		}
		ave = sum/4;
		if(sum%4!=0 || maxlen>ave){			//如果最长的边大于平均边长 
			printf("no\n");
			continue;
		}
		sort(a,a+m);
		memset(vis,0,sizeof(vis));
		flag = 0;
		dfs(0,0,0);
		if(flag==1)	printf("yes\n");
		if(flag==0)	printf("no\n");		
	}
	return 0;
} 

DFS——hdu1518Square

标签:i++   const   form   and   tin   square   between   回顾   put   

原文地址:http://www.cnblogs.com/xzxl/p/7300963.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!