codeforces 269A Magical Boxes 思维问题

本文介绍了一种关于如何将不同尺寸的魔术盒最优地装入一个大魔术盒中的算法。该算法通过排序和逐步合并小盒子到大盒子的方法,确定最小尺寸的大盒子,能够容纳所有小盒子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A. Magical Boxes
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Emuskald is a well-known illusionist. One of his trademark tricks involves a set of magical boxes. The essence of the trick is in packing the boxes inside other boxes.

From the top view each magical box looks like a square with side length equal to 2k (k is an integer, k ≥ 0) units. A magical box v can be put inside a magical box u, if side length of v is strictly less than the side length of u. In particular, Emuskald can put 4 boxes of side length 2k - 1 into one box of side length 2k, or as in the following figure:

Emuskald is about to go on tour performing around the world, and needs to pack his magical boxes for the trip. He has decided that the best way to pack them would be inside another magical box, but magical boxes are quite expensive to make. Help him find the smallest magical box that can fit all his boxes.

Input

The first line of input contains an integer n (1 ≤ n ≤ 105), the number of different sizes of boxes Emuskald has. Each of following n lines contains two integers ki and ai (0 ≤ ki ≤ 1091 ≤ ai ≤ 109), which means that Emuskald has ai boxes with side length 2ki. It is guaranteed that all of ki are distinct.

Output

Output a single integer p, such that the smallest magical box that can contain all of Emuskald’s boxes has side length 2p.

Sample test(s)
input
2
0 3
1 5
output
3
input
1
0 4
output
1
input
2
1 10
2 2
output
3
Note

Picture explanation. If we have 3 boxes with side length 2 and 5 boxes with side length 1, then we can put all these boxes inside a box with side length 4, for example, as shown in the picture.

In the second test case, we can put all four small boxes into a box with side length 2.

如此坑啊 ~~ 本来这道题已经切了~~排名是创历史记录的3道题 排名119 结果rejudge的时候挂了~~掉到了330但也创了历次比赛的最好水平了
题意是这样的
给出的数据时盒子长度的幂和盒子的个数
例如 

1 10

2 2

2

类盒子 一种是长位21次方 ,共有10个 第二种是长为22次方 ,共有2要注意 长为22次方的盒子可以一次装4个长为21次方的盒子
算法:首先按长度排序,然后将前面的小盒子,是否全能放进后面的大盒子中,如果都能放进去的的话,则后面的大盒子的个数不变,否则的话后面的大盒子的个数会发生变化。
下面是这道题的代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
       __int64 len,num;
       }box[110000];
int cmp(node a,node b)
{
   return a.len<b.len;    
}
int main()
{
   int n;
   while(scanf("%d",&n)!=EOF){
   int i;
   for(i=1;i<=n;i++)
      scanf("%I64d %I64d",&box[i].len,&box[i].num);
   sort(box+1,box+1+n,cmp);              //按长度排序  
   int sub,ans,res,j;
   for(i=2;i<=n;i++){            //用下一的大盒子装前面的小盒子
      sub=box[i].len-box[i-1].len;
      if(sub>=15)continue;
      else {
             ans=1;
             for(j=1;j<=sub;j++){           //如果下一个的大盒子能装下前面的小盒子 则大盒子的个数不变
                 ans=ans*4; 
                 if( (ans*box[i].num)>=box[i-1].num)break; //  (1)注意 这里要是__int64 因为题意中有10亿 超过20亿会溢出
                }
             if(ans*box[i].num<box[i-1].num){   //否则多添几个大盒子来装前面的小盒子
                box[i-1].num-=ans*box[i].num;
                box[i].num+=box[i-1].num/ans;
                if(box[i-1].num%ans!=0)box[i].num++;                             
               }
          }    
      }     
    ans=box[n].len;    
    double test=(double)box[n].num-0.1;  //    (2)保证箱子的个数在1<=x<=4 之间位ans+1  4<x<=16是ans+2 16<x<=64 ans+3 依次类推
    if(box[n].num==1){printf("%d\n",ans+1);continue;} 
    while(test>=1){
         ans++;
         test/=4;
         }     
     printf("%d\n",ans);                   
   }     
}






标记(1)位置解决这样的样例
7
1 16777216
2 1000000000   //因为我在代码中乘4 超出20亿 导致数据的错误 应采用__int64
5 65537
6 16384
7 4096
10 64
11 16
ans=17

标记(2)位置解决这样的样例
1
0 268435457
ans=15
样例来保证




有几个地方需要注意:wa了好几次 原文中划红线的语句。
最后装你所拿的最后一个箱子一定要严格大于最后嵌套完成后的箱子
例如
1
1 1
这时需要输入2
边长要严格的大于




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值