codeforces 269A Magical Boxes 思维问题

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
边长要严格的大于




你可能感兴趣的:(codeforces 269A Magical Boxes 思维问题)