uva10123Problem A - No Tipping

1.这道题说是暴力不如说是贪心。文中说往下拿,可以逆向考虑,从空板往上放。首先在(-1.5,1.5)之间的先放上去,因为这个肯定不会造成左支点的左力矩>右力矩和右支点的左支点的力矩<右支点的力矩。然后把<-1.5的放入一个组,>1.5的放入另一个组。这两个组都按力矩大小从小到大排,最后从小到大往上放,直到放完,或无论怎样都不能放上去。

2.文中只有一个小数1.5可以把长度放大。

3.最后答案逆向输出。

#include <iostream>
//#include <cstring>
#include<cstdio>
//#include<cstdlib>
//#include <string>
#include<algorithm>
//#include<cmath>
//#define set0(a) memset(a, 0, sizeof(a))
//#define MARK 2147483647
using namespace std;
struct node
{
    int loc,w;
};
int lon,weight,num;int zz,zy,yz,yy;int zn,yn;node ans[30];int ai;
node znode[30],ynode[30];
bool com(node a,node b)
{
    return a.loc*a.w<b.loc*b.w;
}
int main()
{
// freopen("in.txt","r",stdin);
int cas=1;
  while(scanf("%d%d%d",&lon,&weight,&num))
  {
      if(!lon&&!weight&&!num)break;
      int i;
      lon=2*lon;int loc,w;ai=0;
      zz=0;zy=3*weight;yz=3*weight;yy=0;zn=0;
      yn=0;
      for(i=0;i<num;++i)
      {
          scanf("%d%d",&loc,&w);
          loc=loc*2;
          //cout<<loc<< " "<<w<<endl;
          if(loc>=-3&&loc<=3)
          {   ans[ai].loc=loc/2;ans[ai].w=w;ai++;
              zy=zy+(loc+3)*w;//cout<<ans[ai-1].loc<<endl;
              yz=yz+(3-loc)*w;
          }
          else if(loc<-3)
          {
                  znode[zn].loc=-loc;znode[zn].w=w;++zn;
          }
          else if(loc>3)
          {
               ynode[yn].loc=loc;ynode[yn].w=w;++yn;
          }
          //cout<<ai<<endl;
      }
      sort(ynode,ynode+yn,com);
      sort(znode,znode+zn,com);
      int flag1=0,flag2=0;int flag=1;
      int i1=0,i2=0;
      //printf("s");
      while(1)
      {
           for(;i1<zn;++i1)
           {
               int bi=zz+(znode[i1].loc-3)*znode[i1].w;
               if(bi>zy)break;
               else
               {    flag1=1;
                   zz=bi;ans[ai].loc=-znode[i1].loc/2;
                      ans[ai].w=znode[i1].w;ai++;
                      yz=yz+(znode[i1].loc+3)*znode[i1].w;
               }
           }
           for(;i2<yn;++i2)
           {
               int bi=yy+(ynode[i2].loc-3)*ynode[i2].w;
               if(bi>yz)break;
               else
               {
                   flag2=1;
                   yy=bi;ans[ai].loc=ynode[i2].loc/2;
                   ans[ai].w=ynode[i2].w;ai++;
                   zy=zy+(ynode[i2].loc+3)*ynode[i2].w;
               }
           }
           if(!flag1&&!flag2){flag=0;break;}
           flag1=0;flag2=0;
           if(i1==zn&&i2==yn)break;
      }printf("Case %d:\n",cas++);
      if(flag)
      {
          for(i=ai-1;i>=0;--i)
            printf("%d %d\n",ans[i].loc,ans[i].w);
      }
      else printf("Impossible\n");

  }
    return 0 ;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值