UVA 10123 No Tipping

UVA-10123

题意:给出双支点天平和上面的若干个物块的重量、位置。求一个取出方案,使得取的过程保持平衡。
解题思路:可以反过来想,拿起来要平衡,和放下去平衡是一样的。首先可以确定,两个支点中间的物品只会增加稳定性,不会破坏平衡,所以两个支点之间的物品直接就放上去。其他的物品分为左边和右边,分别根据几何力距从小到大排序(先放小的,可以想一下,如果小的下去都破坏平衡了,肯定要放另外一边的。)然后就是进行计算了。木板的几何力距也要算进去。

##UVA-10123
题意:给出双支点天平和上面的若干个物块的重量、位置。求一个取出方案,使得取的过程保持平衡。
解题思路:可以反过来想,拿起来要平衡,和放下去平衡是一样的。首先可以确定,两个支点中间的物品只会增加稳定性,不会破坏平衡,所以两个支点之间的物品直接就放上去。其他的物品分为左边和右边,分别根据几何力距从小到大排序(先放小的,可以想一下,如果小的下去都破坏平衡了,肯定要放另外一边的。)然后就是进行计算了。木板的几何力距也要算进去。
```c





<div class="se-preview-section-delimiter"></div>

```/*************************************************************************
    > File Name: UVA-10123.cpp
    > Author: Narsh
    > 
    > Created Time: 2016年07月28日 星期四 15时10分20秒
 ************************************************************************/

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
struct node{
    double dis,w;
    double t1,t2;
    int z;
} L[50],R[50];
double l,m,ll,lr,rl,rr,dis[50];
int w[50],n,t,temp[50],key[50],lenr,lenl;
bool vis[50],flag;
bool cmp(node x,node y) {
    return x.t1 <= y.t1;
}
void dfs(int x, int lef, int rig) {
    if (!(ll <= lr && rr <= rl)) return ;
    if (x > n) {
        flag = false;
        for (int i = 1; i <= n; i++)
            key[i]=temp[i];
            //printf("%.0lf %d\n",dis[temp[i]],w[temp[i]]);
        return ;
    }
    if (rig <= lenr) {
        rr+=R[rig].t1;
        lr+=R[rig].t2;
        temp[x] = R[rig].z;
        dfs(x+1,lef,rig+1);
        rr-=R[rig].t1;
        lr-=R[rig].t2;
    }
    if (lef <= lenl) {
        ll+=L[lef].t1;
        rl+=L[lef].t2;
        temp[x] = L[lef].z;
        dfs(x+1,lef+1,rig);
        ll-=L[lef].t1;
        rl-=L[lef].t2;
    }
}
int main() {
    freopen("xx.in","r",stdin);
    int num = 0;
    while (scanf("%lf%lf%d",&l,&m,&n) && l+m+n) {
        rr=ll = (l/2.0-1.5)*(l/2.0-1.5)*m/l/2.0;
        rl=lr = (l/2.0+1.5)*(l/2.0+1.5)*m/l/2.0;
        lenr = lenl = t = 0;
        for (int i = 1; i <= n; i++) { 
            scanf("%lf%d",&dis[i],&w[i]);
            if (-1.5<= dis[i] && dis[i] <= 1.5) {
                temp[++t] = i;
                if (dis[i] > 1.5) rr+=(dis[i]-1.5)*1.0*w[i];
                else rl+=(1.5-dis[i])*1.0*w[i];
                if (dis[i] > -1.5) lr+=(dis[i]+1.5)*1.0*w[i];
                else ll+=(-1.5-dis[i])*1.0*w[i];
            }
            if (dis[i] < -1.5) {
                L[++lenl].dis = dis[i];
                L[lenl].w=w[i];
                L[lenl].t1 = (-1.5-dis[i])*w[i];
                L[lenl].t2 = (1.5 -dis[i])*w[i];
                L[lenl].z=i;
            }
            if (dis[i] > 1.5) {
                R[++lenr].dis=dis[i];
                R[lenr].w=w[i];
                R[lenr].t1 = (dis[i]-1.5)*w[i];
                R[lenr].t2 = (dis[i]+1.5)*w[i];
                R[lenr].z=i;
            }
        }
        printf("Case %d:\n",++num);
        sort(L+1,L+1+lenl,cmp);
        sort(R+1,R+1+lenr,cmp);
        flag = true;
        dfs(t+1,1,1);
        if (flag) printf("Impossible\n");
        else 
            for (int i = n; i >= 1; i--)
                printf("%.0lf %d\n",dis[key[i]],w[key[i]]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值