木棒

依然范特西╮ 提交于 2020-02-03 22:25:52

乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。

然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。

请你设计一个程序,帮助乔治计算木棒的可能最小长度。

每一节木棍的长度都用大于零的整数表示。

输入格式
输入包含多组数据,每组数据包括两行。

第一行是一个不超过64的整数,表示砍断之后共有多少节木棍。

第二行是截断以后,所得到的各节木棍的长度。

在最后一组数据之后,是一个零。

输出格式
为每组数据,分别输出原始木棒的可能最小长度,每组数据占一行。

数据范围
数据保证每一节木棍的长度均不大于50。

输入样例:
9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0
输出样例:
6
5
#include<bits/stdc++.h>

using namespace std;
const int N = 70;
int sti[N], n;
bool use[N];
int sum, len;

inline void init() {
    memset(sti, 0, sizeof(sti));
    memset(use, false, sizeof(use));
    sum = len = 0;
}

inline void read() {
    for (int i = 1; i <= n; i++) {
        scanf("%d", &sti[i]);
        sum += sti[i];
        len = max(len, sti[i]);
    }
    for (int i = 1; i <= n; i++)
        if (sti[i] > 50)use[i] = true;
}

bool dfs(int cnt, int cur, int sta) {
    if (cnt * len == sum)return true;
    if (cur == len)return dfs(cnt + 1, 0, 1);
    for (int i = sta; i <= n; i++) {
        if (use[i])continue;
        int l = sti[i];
        if (cur + l <= len) {
            use[i] = true;
            if (dfs(cnt, cur + l, i + 1))return true;
            use[i] = false;
            if (!cur || cur + l == len)return false;
            while (sti[i + 1] == sti[i])i++;
        }
    }
    return false;
}

inline void solve() {
    while (true) {
        if (sum % len == 0 && dfs(0, 0, 1)) {
            printf("%d\n", len);
            break;
        }
        len++;
    }
}

int main() {
    while (scanf("%d", &n), n) {
        init();
        read();
        sort(sti + 1, sti + n + 1, greater<int>());
        solve();
    }
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!