【CodeForces - 270C】Magical Boxes (思维,进制,有坑)
題干:
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?≤?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
Output a single integer?p, such that the smallest magical box that can contain all of Emuskald’s boxes has side length?2p.
Examples
Input
2 0 3 1 5Output
3Input
1 0 4Output
1Input
2 1 10 2 2Output
3Note
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.
?
題目大意:(練習讀題)
已知一個盒子(2^k)可以套四個小盒子(不能套和自己一樣大的盒子!)
如果一個盒子的邊長大于另一個盒子,那么這個盒子就能夠容納那另一個盒子 。
問用多大邊長的正方形盒子,能夠容納所有給出的盒子。(也就是,如果全程一個盒子,需要再來一個盒子!讀題!)
第一行給出總共盒子數n,下面n行,每行兩個整數,分別代表盒子的大小? 和? 該大小盒子的盒子數量。(其中第一個盒子是用2的冪次給出。)
解題報告:
? 這題我好像做麻煩了,,本來想直接用數組下標代表2的冪次來著,,數量1e9的話也就是說冪次也就幾百而已。。但是發現是冪次是2e9(也就是說這題全程在用冪次,跟具體數字完全無關了),,所以就不能直接用數組了,,考慮用map離散化一波,,不算難寫但是還是有坑的,比如不能直接除以4,,因為不一定相鄰兩個大小的盒子一定是大小相差1的,,仔細理解下就能看出來。(其實看了標解后發現不需要存數據的,,直接on_process一波就ok了)
?
AC代碼1:(直接on出結果的)
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 2e5 + 5; map<ll,ll> mp; int main() {int n;ll ans = 0;ll num,tmp,k;cin>>n;for(int i = 1; i<=n; i++) {scanf("%lld%lld",&k,&num);if(num == 1) k++;while(num > 1) {tmp = num%4 == 0 ? num/4 : num/4+1;num = tmp;k++;}ans = max(ans,k);}printf("%lld\n",ans);return 0 ;} /* 2 0 3 1 5*/AC代碼2:(map處理的)
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 2e5 + 5; map<ll,ll> mp; int main() {int n;ll tmp,num;ll ans = 0;cin>>n;for(int i = 1; i<=n; i++) {scanf("%lld",&tmp);scanf("%lld",&num);ans = max(ans,tmp);mp[tmp] += num;} map<ll,ll> :: iterator it = mp.begin(),end=mp.end(),ii;--end;for(;it != end; ++it) {num = it->se;++it;ii=it;--it;ll pp = pow(4,ii->fi - it->fi);tmp = num%pp == 0 ? num/pp : num/pp + 1;++it;if(it->se < tmp) {it->se += (tmp - it->se); }--it;}num = end->se;if(num == 1) {printf("%lld\n",ans+1);return 0 ;}while(num >= 4) {tmp = num%4 == 0 ? num/4 : num/4 + 1;num=tmp;ans++;}ll out = num == 1 ? ans : ans+1;if(out==0) out=1;printf("%lld\n",out);return 0 ;}總結:? 掌握那種tmp=的那種方式,,經常需要處理一波(記得那次那個記憶化dp的計算幾何題處理邊的時候就需要這樣來著、、)
總結
以上是生活随笔為你收集整理的【CodeForces - 270C】Magical Boxes (思维,进制,有坑)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 银行理财应该选长期还是短期?银行理财的投
- 下一篇: 【ZOJ - 2836 】Number