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 深度优先的主要内容,如果未能解决你的问题,请参考以下文章