ZJFC-1243

2004亚洲赛电梯问题解析

传说中2004年亚洲赛伊朗德黑兰赛区的B题,也是当时比较水的题目,做这道题目用了我2天去想公式,真的是很痛苦的事情,好了,在自己痛苦了几天之后,把代码给贴上吧,都做了详细的注释,是用二分枚举+贪心判定实现的...可我还是不能保证以后碰到后会不会做出来,郁闷的题目.

 

 

 

ContractedBlock.gifExpandedBlockStart.gifCode
#include <iostream>
using namespace std;
bool hash[30010];
long lmax;


bool check( long x )
{
    
long i , j , b;
    b 
= 0;
    
//i为能上的最高层楼
    
//b为电梯停的次数
    i = x/20 + 2;
    
//时间全用做步行,正好不能上的楼层 
    while( i <= lmax )//如果最高层比最高代价能上的层数要高
    {
        
while( i <= lmax && !hash[i] )i++;
        
//i没人就不理它
        if((i - 1)*4 + 10*> x ) return false;
        
//如果坐电梯都上不到i层 那就死吧
        j = ( x - 10*+ 20*+4 )/24;
        
//j=(x-10*b-4*(i-1))/24+i;

        
// x-10*b-4*(i-1)是剩余的时间

        
//24可以看做电梯上 人下的总速度

        
//j表示要达到i层的人,在j层停照样照样走路走得到,i以下的人从前一次停的地点往上走,i到j之间的人从J往下走

        
//电梯不回头 人回头
        
//此时(j)层为停的最适合楼层
        i = ( x - 10*+ 16*+ 4)/20 + 1;//剩下的时间能爬的最高层
        
//i=(x-10*b-(j-1)*4)/20+j+1

        
//x总消耗的时间-坐电梯消耗的时间10*b-上电梯所消耗的时间

        
//这些时间用来步行能上的层数+j层停下的位置+1为最大可上的楼层
        b++;//电梯能停的次数+1
    }
    
//否则通过检验 因为最高代价下都能上到最高层
    return true;
}


int main()
{
    
long n;
    
while (scanf("%ld",&n)!=EOF&&n)
    {
        memset(hash,
0,sizeof(hash));
        
long i;
        lmax
=0;
        
for (i=0;i<n;++i)
        {
            
long floor;
            scanf(
"%ld",&floor);
            hash[floor]
=true;
            
if (floor>lmax)
            {
                lmax
=floor;
            }
        }

        
long low=20*0,high=14*(lmax+1);
        
        
while (low<high)
        {
            
long mid=(low+high)/2;
            
if (check(mid))
            {
                high
=mid;
            }
            
else
            {
                low
=mid+1;
            }
        }
        printf(
"%ld\n",low);
    }
    
return 0;
}

 

 

转载于:https://www.cnblogs.com/zhuangli/archive/2008/07/30/1256469.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值