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.
解题思路:首先对所有的盒子的大小从大到小排序,先挑大的,首先答案至少比最大的盒子的大小大1,之后考虑小盒子与答案尺寸大小之差,差i就是装下4^i个小盒子,这个地方注意一下精度问题,题目说一种盒子的最大数目是10^9个,假设小盒子与答案尺寸之差大于30,一个答案大小的盒子可以装下4^30个小盒子,显然此时不需要对小盒子的数目再去判断,否则就超出了long long的范围了!
#include <iostream>
#include<algorithm>
#include<cmath>
using namespace std;
struct Box
{
long long Size;
long long num;
}box[100005];
bool cmp(Box a,Box b)
{
if(a.Size>b.Size)
return true;
return false;
}
int main()
{
long i,n;
long long temp,ans;
while(cin>>n)
{
temp=-1;
for(i=0;i<n;i++)
{
cin>>box[i].Size>>box[i].num;
if(temp<box[i].Size)
temp=box[i].Size;
}
ans=temp+1;
sort(box,box+n,cmp);
for(i=0;i<n;i++)
{
temp=ans-box[i].Size;
if(temp>30)
continue;
temp=pow(4.0,temp);
while(box[i].num>temp)//某种盒子的数目超出当前答案盒子所能装下的数目,就把答案盒子大小加大1
{
temp*=4;
ans++;
}
}
cout<<ans<<endl;
}
return 0;
}