POJ1011-Sticks 搜索
程序员文章站
2024-03-23 21:45:04
...
Sticks
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 151709 | Accepted: 36124 |
Description
George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.
Input
The input contains blocks of 2 lines. The first line contains the number of sticks parts after cutting, there are at most 64 sticks. The second line contains the lengths of those parts separated by the space. The last line of the file contains zero.
Output
The output should contains the smallest possible length of original sticks, one per line.
一、题意
现在有n根长度不一的小木棒,要求将其拼凑成长度相等的木棒若干。要求输出长度最短的可能。
二、思路
主要思路是搜索,但要加上剪枝才能不超时。搜索时传入剩余的木棒数量,当前已经拼凑的长度。按照我的搜索策略,主要有一下几种剪枝:
1.设拼凑完成后长度为len,则len必定能整除原来木棒的长度和sum。
2.对于新的一次拼凑过程,即当前已经拼凑的长度为0,则要求此次拼凑必须成功。因为若此次拼凑不能成功,意味着存在一根木棒,在以后的搜索过程中都不会完成拼凑。
3.对源木棒进行降序排列,先拼凑长木棒。
4.搜索过程中,对于长度相等的木棒应该避免重复搜索。
即使这样,Discuss中的数据还是要7秒左右。
三、代码
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <utility>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int MAXN = 1000;
const int MOD7 = 1000000007;
const int MOD9 = 1000000009;
const int INF = 2000000000;//0x7fffffff
const double EPS = 1e-9;
const double PI = 3.14159265358979;
const int dir_4r[] = { -1, 1, 0, 0 };
const int dir_4c[] = { 0, 0, -1, 1 };
const int dir_8r[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
const int dir_8c[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
int n;
int val[MAXN];
bool visited[MAXN];
bool myCom(int a, int b) {
return a > b;
}
bool dfs(int left, int cur, int len, int beg) {
if (left == 0 && cur == 0)
return true;
else if (cur == 0) {
//如果是拼接一根新的木棒,则这根木棒必须完成拼接
int index = 0;
while (visited[index])
index++;
visited[index] = true;
if (dfs(left - 1, val[index] % len, len, index + 1))
return true;
visited[index] = false;
return false;
}
for (int i = beg; i < n; ++i)
if (!visited[i])
if (cur + val[i] <= len) {
visited[i] = true;
if (dfs(left - 1, (cur + val[i]) % len, len, i + 1))
return true;
visited[i] = false;
//减少重复搜索
while (i < n && val[i + 1] == val[i])
i++;
}
return false;
}
int main() {
while (scanf("%d", &n) && n) {
int sum = 0;
for (int i = 0; i < n; ++i) {
scanf("%d", val + i);
sum += val[i];
}
sort(val, val + n, myCom);
int len;
for (len = val[0]; len < sum; ++len)
if (sum % len == 0) {
memset(visited, false, sizeof(visited));
if (dfs(n, 0, len, 0))
break;
}
printf("%d\n", len);
}
//system("pause");
return 0;
}
推荐阅读
-
poj1011Sticks(搜索+剪枝)
-
【暴力搜索】[POJ 1011]Sticks
-
poj-1011 sticks(搜索题)
-
POJ1011-Sticks 搜索
-
POJ1011 Sticks 深度优先搜索+剪枝
-
洛谷Function(P1464)记忆化搜索or记忆宏
-
web架构设计经验分享 博客分类: 网站架构 Web敏捷开发数据结构网页游戏搜索引擎
-
互联网创业越简单越容易成功 博客分类: 项目管理 互联网软件测试搜索引擎项目管理工作
-
简单题--700. 二叉搜索树中的搜索
-
分布式搜索elasticsearch集群监控工具bigdesk 博客分类: ElasticSearch 分布式搜索elasticsearch集群监控工具bigdesk監控