POJ 2362 Square 深度优先

Posted 一米阳光213

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2362 Square 深度优先相关的知识,希望对你有一定的参考价值。

大致题意:

有一堆任意长度的小棒子,问他们能否构成一个正方形。

 

解题思路:

与 POJ 1011 Sticks 神似啊,但是简单一点。

// POJ 1011 的精简版
//

#include "stdafx.h"
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int n, a[22];
bool visit[22];			// 所有小棍子的长度
int is_OK;				// 1: 成功   0:待定   -1:必定失败
int target_len;			// 正方形的边长

bool cmp(int a, int b)
	return a > b;


// return:
// true: 成功拼凑
// false: 拼凑失败
bool dfs(int start_index, int finished_sticks, int remaining_length)
	// Step 1: Termination conditions
	if (finished_sticks == 3)   // 剪枝:只要拼完了3根 target_len 棍子,就可以肯定,一定成功
		return true;
	

	// Step 2: Search range
	//int failure_length = -1;
	for (int i = start_index; i < n; i++)
		// Step 3: 排除无效的搜索对象
		//if ( visit[i] ==true || a[i] > remaining_length || a[i] == failure_length) continue;
		if (visit[i]) 
			continue;

		// Step 4: 使用当前的对象,又要分两种情况:刚好凑了一个边长,还是仍有剩余的长度需要拼凑
		visit[i] = true;
		if (a[i] == remaining_length) // 新开一根
			if (dfs(0, finished_sticks + 1, target_len))
				return true;
		
		else if( a[i] < remaining_length)						   // 继续往下搜索
			if (dfs(i, finished_sticks, remaining_length - a[i]))
				return true;
		

		// Step 5: 放弃使用当前的对象
		visit[i] = false;
		// 剪枝:如果第一根小棍子失败了,直接放弃!必定失败
		//if (remaining_length == target_len || start_index ==0 )
		//	return false;
		//
	
	return false;
 

int main(int argc, char * argv[])

	int cases;
	cin >> cases;
	while (cases--)
		scanf("%d", &n);
		int sum = 0;
		for (int i = 0; i < n; i++)
		
			scanf("%d", &a[i]);
			sum += a[i];
		
		is_OK = 0;
		memset(visit, 0, sizeof(visit));
		// 剪枝1:简单的判断一下可行性
		if (sum % 4 != 0 || n<4)
		
			cout << "no" << endl;
			continue;
		
		else
			target_len = sum / 4;
		// 剪枝2:将所有小棍子按长度从大到小排序
		sort(a, a + n, cmp);
		// 剪枝3:如果有小棍子长度 > target_len ,直接失败
		if (a[0] > target_len)
			cout << "no" << endl;
			continue;
		

		// 深度优先搜索
		is_OK = dfs( 0, 0, target_len);
		//is_OK = dfs_std(a, visit, 0, 0, 0);

		if (is_OK == true )
			cout << "yes" << endl;
		else
			cout << "no" << endl;
	
	return 0;

 

以上是关于POJ 2362 Square 深度优先的主要内容,如果未能解决你的问题,请参考以下文章

POJ 1084 Square Destroyer舞蹈链重复覆盖

poj2362

POJ2513(欧拉回路+并查集+字典树)

POJ - 1011 剪枝练习

POJ - 2826 An Easy Problem?!

POJ 2991(线段树)