题目大意:给出一个有两个支点的杆子,杆子的长为L,重为W,上面有N个木块,求如果把木块拿走才能避免天平失去平衡
解题思路:1.将拿木快换成放木块,然后逆序输出就是拿走木块的顺序了
2.将没快木块的力距和重量相乘看成一个整体,然后按从小到达排序,放都是先放轻的,这样避免倾斜,因为两个支点,所有杆子的重量可以加在两边
3.按最小的放,如果放下去了,无论如何都会歪的话,那就结束了,表示怎样拿都会歪的
4.将距离乘以2,避免精度错误
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
int len;
int weight;
};
node left[30],right[30],res[30];
int L,W,N;
int lenl, lenr;
bool flag;
int C;
bool judge(int l, int r) {
int suml = 0, sumr = 0;
for(int i = 0; i < l; i++)
suml = suml + ( -left[i].len * 2 - 3) * left[i].weight;
for(int i = 0; i < r; i++)
sumr = sumr + (right[i].len * 2 + 3) * right[i].weight;
sumr += C;
if(suml > sumr) return false;
suml = 0; sumr = 0;
for(int i = 0; i < l; i++)
suml = suml + ( -left[i].len * 2 + 3) * left[i].weight;
for(int i = 0; i < r; i++)
sumr = sumr + (right[i].len * 2 - 3) * right[i].weight;
suml += C;
if(suml < sumr) return false;
return true;
}
void dfs(int cur, int l , int r) {
if(cur == N) {
flag = true;
for(int i = N - 1; i >= 0 ; i--)
printf("%d %d\n",res[i].len,res[i].weight);
return ;
}
for(int i = l ; i < lenl ; i++)
if(judge(i,r) && !flag) {
res[cur].len = left[i].len;
res[cur].weight = left[i].weight;
dfs(cur+1,i+1,r);
}
else
break;
for(int i = r; i < lenr ; i++)
if(judge(l,i) && !flag) {
res[cur].len = right[i].len;
res[cur].weight = right[i].weight;
dfs(cur+1,l,i+1);
}
else
break;
}
int main() {
int mark = 1;
while(scanf("%d%d%d",&L,&W,&N) != EOF && L ) {
lenl = lenr = 0;
for(int i = 0; i < N; i++) {
int t1,t2;
scanf("%d%d",&t1,&t2);
if(t1 < 0) {
left[lenl].len = t1;
left[lenl++].weight = t2;
}
else {
right[lenr].len = t1;
right[lenr++].weight = t2;
}
}
node temp;
for(int i = 0; i < lenl; i++)
for(int j = i + 1; j < lenl; j++)
if((-left[i].len*2-3)*left[i].weight > (-left[j].len*2-3)*left[j].weight) {
temp = left[i];
left[i] = left[j];
left[j] = temp;
}
for(int i = 0; i < lenr; i++)
for(int j = i + 1; j < lenr; j++)
if((right[i].len*2-3)*right[i].weight > (right[j].len*2-3)*right[j].weight) {
temp = right[i];
right[i] = right[j];
right[j] = temp;
}
C = 3 * W;
flag = false;
printf("Case %d:\n",mark++);
dfs(0,0,0);
if(!flag)
printf("Impossible\n");
}
return 0;
}