poj 2362:Square

解題思路:

DFS+剪枝

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
using namespace std;

int m,n,s;
int stick[25];
bool used[25];
bool flag;

int cmp(const void * a, const void * b)
{
	return *(int *)b - *(int *)a;
}
//sum 表示已獲取邊長數
//l 表示已拼湊的長度
//t 搜索下一根木棍的開始位置 
void func(int sum,int l,int t)
{
	if(flag)
		return;
	if(sum == 4)
	{
		flag = true;
		return;
	}
	//得到一條完整的邊 
	if(l == s/4)
	{
		func(sum+1,0,0);
		return;
	}
	for(int i=t;i<n;i++)
	{
		if(flag)
			return;
		//若某條木棍與已得長度相加等於邊長,則不必嘗試使用其他木棍 
		if(stick[i] + l == s/4 && !used[i])
		{
			used[i] = true;
			func(sum,stick[i] + l,0);
			used[i] = false;
			return;
		}
		else if(stick[i] + l < s/4 && !used[i])
		{
			used[i] = true;
			func(sum,stick[i] + l,i+1);
			used[i] = false;
		}
	}
	return;
}

int main()
{
	scanf("%d",&m);
	while(m--)
	{
		scanf("%d",&n);
		s = 0;
		memset(used,0,sizeof(used));
		flag = false;
		int maxl = 0;
		for(int i=0;i<n;i++)
		{
			scanf("%d",&stick[i]);
			s += stick[i]; 
			if(stick[i] > maxl)
				maxl = stick[i];
		}
		//若存在木棍超出邊長 或者 總長度不是4的整數倍,輸出“no” 
		if(s % 4 != 0 || maxl > s /4)
		{
			printf("no\n");
			continue;
		}
		//從大到小排序 
		qsort(stick,n,sizeof(stick[0]),cmp);
		//從零開始搜索 
		func(0,0,0);
		if(flag)
			printf("yes\n");
		else
			printf("no\n");
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章