Acwing - 167 木棒

探讨了一道经典的计算机科学问题——如何通过已知的木棒碎片,逆向推算出原始木棒的最短可能长度。问题设定为乔治有一组被随机砍断的等长木棒,每段长度不超过50个单位,需重建原状但忘记原始长度和数量,通过设计程序解决这一挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                                                            167 木棒

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

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

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

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

注意: 数据中可能包含长度大于50的木棒,请在处理时忽略这些木棒。

输入格式

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

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

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

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

输出格式

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

输入样例:

9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0

输出样例:

6
5

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
const int MAX= 10005 ;
int a[MAX]  ;
int n ;
int vis[MAX] ;
int cnt ;
int len ;
bool cmp(const int &x , const int &y) {
	return x>y ;
}
bool dfs(int stick , int cab , int last){
	// 当前正在拼第stick 根, 当前凑到cab长度了,
	if(stick > cnt)  return true ; // 如果当前已经拼完cnt根,说明可以
	if(cab == len ) return dfs(stick+1,0,1) ; // 如果当前已经拼到len 了, 再凑下一根木棍
	int fail = 0 ;// 记录上一次失败的木根
	for(int i = last ; i<=n ; i++ ) {
		if(!vis[i] && cab +a[i] <= len && fail !=a[i]){
			// 如果还没有用过这个木根,
			// 且 当前长度 + 这个木根的长度小于等于答案
			vis[i] = 1 ;
			if(dfs(stick,cab+a[i],i+1))return true ;
			// 回溯,
			fail = a[i] ; //剪枝,
			vis[i] = 0 ;
			if(cab == 0 ) return false; // 如果在一根原始木棒中尝试拼接的第一根木棍的递归分支就以失败返回
		}
	}
	return false ; // 所有分支都尝试过,没找到,
	
}
int main(){
	while(cin >> n && n) {
		int sum = 0 ,val = 0 ;
		for(int i = 1 ; i<=n ;i++ ) {
			scanf("%d",&a[i]);
			sum+=a[i] ;
			val = max(val,a[i]) ;
		}
		sort(a+1 ,a+1+n,cmp) ;
		// 从最小的可能开始枚举答案
		for( len = val ; len <=sum ; len++) {
			if(sum%len == 0 ){
				cnt = sum/len ; // 原始有几根木棍
				memset(vis,0,sizeof(vis)) ;
				if(dfs(1,0,1)) break ;
			}
		}
		cout<<len <<endl;
	}
	
	
	return 0 ;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值