标签:
The challenge is to keep the lever balanced while adjusting theobjects on it. Assume you have a straight, evenly weighted board, 20meters long and weighing three kilograms. The middle of the board isthe center of mass, and we will call that position 0. So the possiblepositions on the board range from -10 (the left end) to +10 (the rightend). The board is supported at positions -1.5 and +1.5 by two equalfulcrums, both two meters tall and standing on a flat floor. On theboard are six packages, at positions -8, -4, -3, 2, 5 and 8, havingweights of 4, 10, 10, 4, 7 and 8 kilograms, respectively as in thepicture below.
You are to write a program which solves problems like the onedescribed above. The input contains multiple cases. Each case startswith three integers: the length of the board (in meters, at least3), the weight of the board (in kilograms) and n thenumber of packages on the board (n <= 20).The board is supported at positions -1.5 and +1.5 by two equalfulcrums, both two meters tall and standing on a flat floor.The following n lines contain two integers each: the position of apackage on board (in meters measured from the center,negative means to the left) and the weight of the package (inkilograms). A line containing three 0‘s ends the input. For eachcase you are to output the number of the case in the format shownbelow and then n lines each containing 2 integers, theposition of a package and its weight, in an order in which the packagescan be removed without causing the board to tip. If there is nosolution for a case, output a single line Impossible. Thereis no solution if in the initial configuration the board is notbalanced.
20 3 6 -8 4 -4 10 -3 10 2 4 5 7 8 8 20 3 15 1 10 8 5 -6 8 5 9 -8 4 8 10 -3 10 -4 5 2 9 -2 2 3 3 -3 2 5 1 -6 1 2 5 30 10 2 -8 100 9 91 0 0 0Possible Output for sample input
Case 1: -4 10 8 8 -8 4 5 7 -3 10 2 4 Case 2: 1 10 8 5 -6 8 5 9 -8 4 8 10 -3 10 -4 5 2 9 -2 2 3 3 -3 2 5 1 -6 1 2 5 Case 3: Impossible 我刚開始是直接DFS,果断超时了。然后參考了别人的算法,例如以下:(抄自hackerwin7的专栏)题解:两种方法。
一、DFS剪枝+物理力矩+贪心二、状态压缩+记忆话搜索 ...
一:将放上去的砝码做一个逆变换,即初始化为杠杆上没有砝码。我们一个一个往上放。使其过程中不发生側翻的情况。
側翻的情况:当左边点的左端的力矩大于左边点的右端的力矩,会往左側翻。当右边点的右端的力矩大于右边点的左端的力矩。会往右側翻。
注意点:
1、处理时将坐标放大两倍。使1.5->3省略小数的处理。
2、处于-1.5~+1.5之间的先放,能够证明其不会影响杠杆的側翻(剪枝)。
3、在此区间以外的分为两组。-L~-1.5为左组 +1.5~+L为右组,将两组按相应点力矩升序排列,放砝码时,若放最大的,非常可能会引起側翻,
所以尽可能维持平衡,从影响度最小的開始放,再放大的,这样到后面这些若干小的能够缓和还有一側大的砝码的側翻影响效应,从而尽可能维持平衡
(若实在无法维持平衡 那就是impossible)。所以整个DFS过程能够贪心地去一边的砝码,比方左边的按升序先放砝码,一直到左边再放一个就
会引起側翻后,再到右边的按升序放,用来抑制左边会側翻的情况。若左边还是側翻继续往右边放。直到左边能够放为止,注意左右两组砝码都是有序
的,这样省去了无序砝码的遍历查找时间(剪枝)。一直维持这个过程。直到全部砝码都放上去,也没有出现側翻的条件就ok;假设出现这种情况,无
论放左边还是放右边的都有側翻情况发生,那么这一种情况就是impossible的。(感觉这种模式与快排的算法模式有点相似。
AC的代码例如以下:
标签:
原文地址:http://www.cnblogs.com/mengfanrong/p/5094974.html