Miku's Boxes(简单题数学题)

这道题目是关于如何将不同大小的立方体盒子(边长为2^k[i])收纳进一个大盒子中,使得大盒子的边长为2^A,A为求解的目标。解题方法包括将小正方体个数转化为新的指数,并计算每个小盒子能放入的最小大盒子的边长,最后找出满足条件的最大边长A。

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

题目链接:http://cstest.scu.edu.cn/soj/contest/contest.action?cid=332

A: Miku's Boxes

Description

When Miku cleans up the warehouse, She finds some boxes. All the boxes are cube, and the width of the i-th box is Ci=2^ki. Now, Miku prepares to throw these boxes away, but throwing them one by one is terrible, so she decides to put all boxes into a big box and throws it. Miku finds that only when box A's width is less than box B's, A can be put into B, and 8 boxes which width is 2^(k-1) can be put into 1 box which width is 2^k particular.

Now, please help Miku calculate how big of a box she needs to put all boxes into.

(If the biggest boxes of these boxes can meet the conditions, Miku will use this box, otherwise she will make a new box. Details please refer to the Sample Input.)

Input

The first line of input T is the number of test case.

There are three lines of each test case.

First, a integers n, means Miku find n different boxes.( 0 < n <= 50000)

Second, n intergers, k1, k2 ... kn, and ki means the i-th different box's width is 2^ki(0<=ki<=50000).

Third, n intergers, m1, m2 ... mn, and mi means the number of the i-th different box (1<=mi<=10000).

Output

For each test case output a interger K means the box's width is 2^K which Miku needs.

Sample Input

2

1

0

8

2

0 1

8 1

Sample Output

1

1

Hint

In test 1,Miku make a new box of 1 width.

In test 2,Miku use the 1 width's box her find in warehouse.

Author

qw4990

题意:给你一系列正方体盒子的边长2^k[i],及其相应个数m[i],

求最终用一个盒子的边长:2^a,该盒子可以一次性把一种正方体盒子全部装进去

解题方法:

法一:

/*目的:A,其中A是这样定义的:最大的正方体边长为2^A思路:利用两点:一~最终要求的始终是正方形,Vmax=(2^A)^3=2^(A*3); 

二,利用幂的乘法的优越性可避免大数相乘;   

        步骤:           

1,化2^j=i;将小正方体个数j化为f[j]=i表示为(2^i>=j&&2^(i-1)<j)(这样做的目的是使多余部分也能整合成正方体)          

 2,求每种正方体可以放进的最小正方体箱子。Vi=2^(3*k[i]+f[m[i]]+2)=2^(3*Ai),Ai=(3*k[i]+f[m[i]]+2)/3;         

  3,一步步比较求A  

*/#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std
;const int maxn=50000+10;
int k[maxn],m[maxn],f[maxn];
int main()
{  int n,i,j,max,t,ans;
  int T;  scanf("%d",&T); 
 f[1]=0; t=1;  i=1; 
 while(t<=10000) //这里的f[j]=i表示为(2^i>=j&&2^(i-1)<j)  
{   for(j=t+1;j<=t*2;j++)
   {f[j]=i;   //printf("f[%d]=%d\n",j,i);  
 }    t=t*2;    i++;} 
 while(T--)  
   {        
   scanf("%d",&n);           
  for(i=0;i<n;i++)          
 scanf("%d",&k[i]);         
  for(j=0;j<n;j++)        
   scanf("%d",&m[j]);        
   max=0;          
 for(i=0;i<n;i++)           
 {        
 ans=(3*k[i]+f[m[i]]+2)/3;//根据幂的乘法性质可得                   
   //printf("%d  ",ans);                     
 if(max<ans)                     
 max=ans;           
 }         
   printf("%d\n",max); 
  }   
 return 0;
}
法二:其实也是利用了以上的性质,只不过是直接推出最终结果的
#include<stdio.h>
#include<iostream>
#include<fstream>
using namespace std;
#define maxn 50009
int k[maxn],m[maxn],n;
int main()
{
    int t;
    cin >> t;
    while(t--)
{
        cin >> n;
        for(int i=1;i<=n;i++)
            cin >> k[i]; //输入正方体边长(2^k[i])
        for(int i=1;i<=n;i++)
            cin >> m[i];//个数
        int ans = -1;
        for(int i=1;i<=n;i++)
{
            int K = k[i],tmp = 1;
            while(tmp < m[i])
           {
                tmp *= 8;//因为8=2^3,V=2^((K+1)*3)=2^(K*3)*8=2^(k[i]*3)*(tmp*8);
                K++;//边长取最大值
            }
            ans = max(ans,K);
        }
        cout << ans << endl;
    }
    return 1;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值