链接:
题意:
现在有一块玻璃,是长方形的(w 毫米× h 毫米),现在要对他进行切割。
切割的方向有两种,横向和纵向。每一次切割之后就会有若干块玻璃被分成两块更小的玻璃。在切割之后玻璃不会被移动。
现在想知道每次切割之后面积最大的一块玻璃是多少。
样例解释:
![](https://i-blog.csdnimg.cn/blog_migrate/12a15f90634e352dd8010e17afac85b7.png)
对于第四次切割,下面四块玻璃的面积是一样大的。都是2。
输入样例
4 3 4
H 2
V 2
V 3
V 1
输出样例
8
4
4
2
思路:
这道题的思路不是很难,关键是编码,很考验编码能力,我从构思到通过,想到了3种方法,但是最后都发现不好编码放弃了,最后想了个版本,通过了,在51nod效率榜上居然是第3。
说一下我的思路吧,处理方法就是先按步骤划分,然后从尾到头,将玻璃合并,在合并过程中维护玻璃的最大值。
关键是编码,我用了结构体,有is_cut,l,r三个字段,横和纵分别处理,在划分过程中,除了标记
is_cut以外,就是算出l和r的值,它们表示当前划分处离它们左右两个划分处的距离,当它们算出来后。
在合并的时候就很方便了,比如横向上要合并x这个位置,那么x.l+x.r就是合并后的新距离,只要把这个新距离赋值给x划分处的前后两个划分处的l和r就行了,也就是[x+x.l].r=x.l+x.r,[x-x.r].l=x.l+x.r。
这种处理方法无论在时间复杂度还有空间复杂度上都是很不错的。
AC代码:
#include<bits/stdc++.h>
#define ll long long
#define endl "\n"
const int N=2e5+5;
const int INF=0x3f3f3f3f;
const int MOD=1e9+7;
const double eps=1e-6;
using namespace std;
struct A{
ll l,r;
bool is_cut;
}W[N],H[N];
int w,h,n,x;
char c;
void run(){
cin>>w>>h>>n;
W[w].is_cut=true,H[h].is_cut=true;
vector<pair<char,int>> re;
while(n--){
cin>>c>>x;
re.push_back({c,x});
if(c=='H') H[x].is_cut=true; //横向切割-》h
else W[x].is_cut=true; //-》w
}
ll mavH=-1,mavW=-1,cur=0,res=-1;
for(int i=1;i<=h;++i) if(H[i].is_cut) H[i].r=i-cur,mavH=max(mavH,i-cur),cur=i;
cur=h;
for(int i=h-1;i>=1;--i) if(H[i].is_cut) H[i].l=cur-i,cur=i;
cur=0;
for(int i=0;i<=w;++i) if(W[i].is_cut) W[i].r=i-cur,mavW=max(mavW,i-cur),cur=i;
cur=w;
for(int i=w-1;i>=1;--i) if(W[i].is_cut) W[i].l=cur-i,cur=i;
res=max(res,mavH*mavW);
vector<ll> ans;
ans.push_back(res);
reverse(re.begin(),re.end());
re.pop_back();
for(auto each:re){
if(each.first=='H'){
ll len=H[each.second].l+H[each.second].r;
H[each.second+H[each.second].l].r=len;
H[each.second-H[each.second].r].l=len;
mavH=max(mavH,len);
}else{
ll len=W[each.second].l+W[each.second].r;
W[each.second+W[each.second].l].r=len;
W[each.second-W[each.second].r].l=len;
mavW=max(mavW,len);
}
res=max(res,mavH*mavW);
ans.push_back(res);
}
reverse(ans.begin(),ans.end());
for(auto each:ans) cout<<each<<endl;
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
freopen("../input.txt","r",stdin);
freopen("../output.txt","w",stdout);
int _=1;
//cin>>_;
for(int i=0;i<_;++i) run();
return 0;
}