HDU 1455 Sticks

这题让我看解题报告都感觉弱无力的样子,囧rz

题意:

几根原本长度相同的木棒,然后被某人当出气筒剪啊剪啊,剪成好几段,然后,好吧,这时间一长记性就差了,忘了原来这堆木棒的长度。

输出可能的最短长度

如果说思路大概懂,但是代码看不懂,最好的办法就是在纸上模拟,或者把别人代码在计算机上一步一步跟踪调试。

首先原长可能的范围:

最短也比剪断后的最长木棒长(或者相等),最长可能就是由一根木棒剪出来的

另外,原木棒长度必然是木棒总长的因数

 

再解释一下代码中DFS各个参数的含义

bool DFS(int len, int l, int count, int pos)
  • len:假设原木棒长度为len,进行搜索。搜索过程中len是不变的
  • l:一个长为len的木棒,可能是由多个剪断后的木棒拼接而成。l表示当前正在还原的木棒的长度,也就是说还需要一个或多个总长为len-l的木棒就能还原成一个长为len的木棒
  • count:如果总长sum,原长为len,则原来一共有sum/len根木棒,count则记录着已经拼好了多少根长为len的木棒
  • pos:此次要拼的木棒的位置

 

 1 #define LOCAL

 2 #include <iostream>

 3 #include <cstdio>

 4 #include <cstring>

 5 #include <algorithm>

 6 using namespace std;

 7 

 8 struct Stick

 9 {

10     int lenth;

11     bool used;    //    该木棒是否已经用于拼接

12 }sticks[55];

13 

14 int n, num, sum;

15 

16 bool cmp(Stick a, Stick b)

17 {

18     return (a.lenth > b.lenth);

19 }

20 

21 bool DFS(int len, int l, int count, int pos)

22 {

23     if(len == sum)

24         return true;

25     if(count == num)

26         return true;    //num根木棒已经全部拼接完成

27     for(int i = pos; i < n; ++i)

28     {

29         if(sticks[i].used)

30             continue;

31         if(len == sticks[i].lenth + l)

32         {

33             sticks[i].used = true;

34             if(DFS(len, 0, count + 1, 0))    //拼好一根,拼下一根

35                 return true;

36             sticks[i].used = false;

37             return false;

38         }

39         else if(len > sticks[i].lenth + l)

40         {

41             sticks[i].used = true;        //一根拼不完,先拼上

42             l += sticks[i].lenth;

43             if(DFS(len, l, count, i + 1))

44                 return true;

45             sticks[i].used = false;

46             l -= sticks[i].lenth;

47             if(l == 0)

48                 return false;        //这一句不是特别理解 =_=!!

49             while(sticks[i].lenth == sticks[i + 1].lenth)

50                 ++i;    //如果两根长度相等,这根长度不符合那么下一根也一定不行

51         }

52     }

53     return false;

54 }

55 

56 int main(void)

57 {

58     #ifdef LOCAL

59         freopen("1455in.txt", "r", stdin);

60     #endif

61 

62     while(scanf("%d", &n) && n)

63     {

64         sum = 0;

65         for(int i = 0; i < n; ++i)

66         {

67             scanf("%d", &sticks[i].lenth);

68             sticks[i].used = false;

69             sum += sticks[i].lenth;

70         }

71         sort(sticks, sticks + n, cmp);

72 

73         for(int len = sticks[0].lenth; len <= sum; ++len)

74         {

75             if(sum % len != 0)

76                 continue;

77             num = sum / len;

78             if(DFS(len, 0, 0, 0))

79             {

80                 printf("%d\n", len);

81                 break;

82             }

83         }

84     }

85     return 0;

86 }
代码君

 

你可能感兴趣的:(HDU)