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;
}

 

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