欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

蓝桥杯: 算法训练 Sticks(POJ1011)

程序员文章站 2022-06-03 18:30:27
...

问题描述
  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.
输入格式
  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.
输出格式
  The output should contains the smallest possible length of original sticks, one per line.
样例输入
9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0
样例输出
5
6
蓝桥杯上找的题目,但怎么都过不了(一直运行超时),我太抑郁了,然后去网上搜。发现是POJ1011的原题,然后我就去试下,居然过了。我也不知道什么原因,还是菜啊????。
附上菜鸡过程(人还是很执着的(●’◡’●)):
蓝桥杯: 算法训练 Sticks(POJ1011)

#include <iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
//#include<bits/stdc++.h>
using namespace std;
const int maxn = 100;
int n;
int a[maxn];
int book[maxn];
int flag = 0;
void dfs(int s, int index,int sum,int usn) {
  //  cout << s << " " << index << " " << sum << " " << usn << endl;
    if(flag==1){
        return;
   }
    if (s == sum) {
       // cout << usn << endl;
        if (usn == n) {
            flag = 1;
        }
        else {
            dfs(0, 0, sum, usn);
        }
        return;
    }
    if (s == 0) {
        while (book[index]!=0) {
            index++;
        }//找到最大的树枝
        book[index] = 1;
        dfs( a[index], index+1, sum, usn + 1);
        book[index] = 0;
    }
    else {
        for (int i = index; i < n; i++) {
            if (book[i] != 1 && (s + a[i]) <= sum) {
                if (book[i - 1] == 0 && a[i] == a[i - 1]) {//如果相同,就不用搜了 减枝
                    continue;
                 }
               //  cout << s + a[i] << endl;
                book[i] = 1;
                dfs(s + a[i], i +1, sum, usn + 1);
                book[i] = 0;
            }
        }
    }
}
bool cmp(int x, int y) {//大到小排序
    return x > y;
}
int main()
{
    ios::sync_with_stdio(0);//输入输出流的加速
    int maxx = -1;
    int sum = 0;
    while (cin >> n && n) {
        maxx = -1;
        sum = 0;
        flag = 0;
        for (int i = 0; i < n; i++) {
            cin >> a[i];
            maxx = max(maxx, a[i]);
            sum += a[i];
        }
        sort(a, a + n,cmp);
        for (int i = maxx; i <= sum; i++) {//枚举最长的木棍,到所有木棍和的总和
            if ((sum % i)==0) {//如果不能整除,意味着在分的时候也没有办法整除,比如一共能分为 3组 那么sum%3==0
                memset(book, 0, sizeof( book));
                for (int j = 0; j < n; j++) {
                    book[j] = 0;
                }
                dfs(0,0,i,0);
                if (flag == 1) {
                    cout << i << endl;
                    break;
                }
            }
        }
    }
    return 0;
}