码迷,mamicode.com
首页 > 其他好文 > 详细

小木棍 (codevs 3498)题解

时间:2015-05-17 21:36:36      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:

【问题描述】  

    乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过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.

 

小木棍 (codevs 3498)题解

标签:

原文地址:http://www.cnblogs.com/PengBoLiuXu/p/4510367.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!