小木棍 (codevs 3498)题解

【问题描述】  

    乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过100。

   现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。

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

【样例输入】

     9 

    5 2 1 5 2 1 5 2 1

【样例输出】

     6

【解题思路】

     这道题的核心思想就一个字,搜……首先找到最大的那一段,原始木棍的可能长度必定>=最大的那一段木棍的长度,所以我们从最大的那一段长度开始往木棍总长度搜,将木棍排序,定义f布尔型数组,用来存该木棍是否用过,由于最终必定每一根木棍都可以成为组成的一部分,因此我们只要碰到没用过的就搜即可,如果有一根无法组成,那就不是原始木棍的长度,搜下一个长度,详见代码。

【代码实现】

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

 2     f:array[0..100] of boolean;

 3     n,i,s,maxn,now,j:longint;

 4     flag:boolean;

 5 procedure sort(l,r: longint);

 6       var

 7          i,j,x,y: longint;

 8       begin

 9          i:=l;

10          j:=r;

11          x:=a[(l+r) div 2];

12          repeat

13            while a[i]<x do

14             inc(i);

15            while x<a[j] do

16             dec(j);

17            if not(i>j) then

18              begin

19                 y:=a[i];

20                 a[i]:=a[j];

21                 a[j]:=y;

22                 inc(i);

23                 j:=j-1;

24              end;

25          until i>j;

26          if l<j then

27            sort(l,j);

28          if i<r then

29            sort(i,r);

30       end;

31 function pd(sum,v:longint):boolean;

32 var i:longint;

33 begin

34  pd:=false;

35  if sum=now then

36   exit(true);//如果等于当前所搜的长度,就暂时是正确的,可以搜其他没有搜的木棍

37  if sum>now then

38   exit(false);//如果大于了,那么就剪枝,搜下一根木棍

39  for i:=v downto 1 do

40   if f[i] then

41    if pd(sum+a[i],i-1) then

42     begin

43      f[i]:=false;

44      exit(true);

45     end;

46 end;

47 begin

48  readln(n);

49  for i:=1 to n do

50   begin

51    read(a[i]);

52    s:=s+a[i];

53    if a[i]>maxn then

54     maxn:=a[i];

55   end;

56  sort(1,n);

57  for i:=maxn to s do//从最长的搜到总长

58   if s mod i=0 then

59    begin

60     now:=i;

61     flag:=true;

62     fillchar(f,sizeof(f),true);

63     for j:=n downto 1 do

64      if f[j] then

65       if not pd(0,j) then//凡是没有用过的木棍都要搜一遍,只要有一根不能组成就搜下一个长度

66        begin

67         flag:=false;

68         break;

69        end;

70     if flag then

71      begin

72       writeln(i);

73       halt;

74      end;

75    end;

76 end.

 

你可能感兴趣的:(code)