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 }