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.
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 ≤ 109, 1 ≤ ai ≤ 109), which means that Emuskald has ai boxes with side length 2ki. It is guaranteed that all of ki are distinct.
Output a single integer p, such that the smallest magical box that can contain all of Emuskald’s boxes has side length 2p.
2 0 3 1 5
3
1 0 4
1
2 1 10 2 2
3
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但也创了历次比赛的最好水平了
题意是这样的 给出的数据时盒子长度的幂和盒子的个数 例如
2
1 10
2 2
2
类盒子 一种是长位2的1次方 ,共有10个 第二种是长为2的2次方 ,共有2个 要注意 长为2的2次方的盒子可以一次装4个长为2的1次方的盒子 算法:首先按长度排序,然后将前面的小盒子,是否全能放进后面的大盒子中,如果都能放进去的的话,则后面的大盒子的个数不变,否则的话后面的大盒子的个数会发生变化。
下面是这道题的代码:
#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);
}
}7 1 16777216 2 1000000000 //因为我在代码中乘4 超出20亿 导致数据的错误 应采用__int64 5 65537 6 16384 7 4096 10 64 11 16ans=17
1 0 268435457

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

被折叠的 条评论
为什么被折叠?



