题意:
给出一个高为 H ,宽为 V 的矩形。要经过 N 次切割,问每次切割后最大的一块是多少?
思路:
为简化思考,本题题意为二维切割,我们不妨先考虑将问题转化为一位线段的切割问题思考。
我们可以通过维护 切点 及 从每个切点开始的线段长度 得知每次操作后的最大长度。
即 利用 数组 维护从每个切点开始的线段长度
利用 set 维护 切点
利用 multiset 维护 所有线段的长度 以便求最大长度
在增加切点时利用 set 的二分查找和 multiset 的相关操作可以将效率压在 log(N)。
二维,多维同理
代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN=2e5+100;
set <int> x;
set <int> y;
set <int>::iterator it;
multiset <int> ansx;
multiset <int> ansy;
multiset <int>::iterator it1,it2;
int lenx[MAXN];
int leny[MAXN];
char ch;
int n,m,k,v,temp;
long long mh,mv;
void ini(){
x.clear();ansx.clear();
y.clear();ansy.clear();
memset(lenx,0,sizeof(lenx));memset(leny,0,sizeof(leny));
ansx.insert(n); ansy.insert(m);//...........................最初的线段长度,即线段的总长
x.insert(0);y.insert(0);
x.insert(n);y.insert(m);//..................................将线段头尾设置为切点
lenx[0]=n;lenx[n]=0;//......................................将线段头尾设成切点后,切点对应的线段长度
leny[0]=m;leny[m]=0;
}
int main()
{
ios::sync_with_stdio(false);
while(cin>>n>>m>>k){
ini();
while(k--){
cin>>ch>>v;
if(ch=='H'){
it=y.lower_bound(v);--it;//.....................找到添加切点