31分之13怎么用计算机算,宁波市第31届小学生计算机程序设计初赛试题

2.拼木棍

有一些同样长的木棍,把这些木棍随意砍成几段。现在,他想把小木棍拼接成原来的的样子,但是忘记了自己开始时有多少根木棍和它们的的长度。

给出每段小木棍的长度,编程找出原始木棍的最小可能长度。

输入第一行为一个单独的整数N表示砍过以后的小木棍的总数。笫二行为N个用空格隔开的正整数,表示N根小木棍的长度,输出仅一行,表示要求的原始木棍的最小可能长度。

样例输入:

9

5 2 1 5 2 1 5 2 1

样例输出:

6

解题思路:

枚举原始木棍长度,然后验证小木棍是否能拼凑出该枚举长度的整数倍,但要充分利用题目的隐含的信息进行优化,不然会超时

优化1:原始木棍长度>=最大的小木棍长度,原始木棍长度<=小木棍长度之和

优化2:小木棍的长度之和一定是原始的木棍长度的倍数

优化3:小木棍应该由大到小去拼凑枚举出来的原始木棍长度

优化4:当每次尝试接入小木棍后,大木棍未达到要求长度时,尝试接入的下一根小木棍要和刚刚接入小木棍和长度不相等

优化5:当一个小木棍接入后,刚好达到原始木棍长度,在以后的尝试中没有必要用更小的小木棍代替这个刚接入的小木棍

根据以上解题思路完善如下程序var

n,i,L,max,sum,j:longint;

a:array[0..100] of longint;

visit:array[0..100] of boolean;

procedure dfs(k,now:longint);

var

i,last:longint;

begin

if (k>n) and (now=0) then

begin

writeln(L);

halt;//退出整个程序

end;

if k>n then exit;

last:=0;

for i:=1 to n do

if (not(visit[i])) and (now+a[i]<=L) and (a[i]<>last) then

begin

visit[i]:=true;

if (now+a[i]=L) then

begin

dfs(k+1,0);

visit[i]:=false;

exit;//这里的退出体现了优化5

end;

dfs(k+1,now+a[i]);

visit[i]:=false;

last:=a[i];

if now=0 then exit;

end;

end;

begin

readln(n);

i:=n;

while i>0 do

begin

read(L);

inc(sum,L) ;

a[i]:=L;

i:=i-1;

if L>max then max:=L;

end;

for i:=1 to n do

for j:=i+1 to n do

if a[i]

begin

L:=a[i];

a[i]:=a[j];

a[j]:=L;

end;

for L:=max to sum do//枚举原始木棍长度L长度时由小到大枚举.利用优化1

if sum mod L=0 then //优化 2

dfs(1,0);

end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值