洛谷P4147玉某宫(最大矩阵好题)
題目描述
這片土地被分成N*M個格子,每個格子里寫著'R'或者'F',R代表這塊土地被賜予了rainbow,F代表這塊土地被賜予了freda。
現在freda要在這里賣萌。。。它要找一塊矩形土地,要求這片土地都標著'F'并且面積最大。
但是rainbow和freda的OI水平都弱爆了,找不出這塊土地,而藍兔也想看freda賣萌(她顯然是不會編程的……),所以它們決定,如果你找到的土地面積為S,它們每人給你S兩銀子。
輸入輸出格式
輸入格式:
第一行兩個整數N,M,表示矩形土地有N行M列。
接下來N行,每行M個用空格隔開的字符'F'或'R',描述了矩形土地。
輸出格式:
輸出一個整數,表示你能得到多少銀子,即(3*最大'F'矩形土地面積)的值。
輸入輸出樣例
輸入樣例#1:
5 6 R F F F F F F F F F F F R R R F F F F F F F F F F F F F F F輸出樣例#1:
45\(Solution:\)
一道傻不拉幾的求最大矩形面積題qwq
首先處理一個 p 數組,表示向上可拓展多少高度,是 “ F ” 就從上面那個轉移過來,是 “ R ” 就等于 0 。然后枚舉每一行,對于每一行求一個最大矩形面積
重點來了,怎么求最大矩形面積?請聽下回分解
開一個棧,用來記錄單調上升的矩陣,接下來的矩陣如果高度大于 top ,就加進去;如果小于,就把棧彈到大于為止,即把棧中高于當前矩陣的矩陣彈掉并處理一下,并且每一次彈棧時都記錄一下答案。
如果有這么一個圖:
首先一直加,不需要記錄答案,直到第5個矩陣:
那么就把第3,4號矩陣彈掉,并相應地把2號矩陣的寬度改掉,即改成這種樣子:
在過程中開一個指針leng,表示你彈掉的矩陣的總長度,在每彈一個時計算一下答案:\(leng * l[top].hi\) 。比如彈第三個時:
此時 leng=2 ,\(l[top].hi\) 為第三個矩陣的高度,計算的是藍色區域的面積。
最后把第4號的寬度也加進去,所以棧中有兩個元素,第一號寬度為 1 ,第二個為 4 。
跑完時一定要記得把棧清空,彈棧的程序一樣,也要計算答案。
具體請配合代碼食用:
#include<bits/stdc++.h> using namespace std; inline int read(){int f=1,w=0;char c=0;while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)) w=w*10+(c^48),c=getchar();return f*w; } struct line{int le,hi; }l[1010];//棧 int T,n,m,p[1010][1010],s[1010],ans; int check(int q){int tp=1,res=p[q][1];l[1].hi=res,l[1].le=1;for(int i=2;i<=m;i++){if(p[q][i]>=l[tp].hi){l[++tp].le=1;l[tp].hi=p[q][i];}//高度大于,直接加棧else{int leng=0;while(l[tp].hi>p[q][i]){leng+=l[tp].le;res=max(res,leng*l[tp].hi);//彈的時候記錄一下答案tp--;}l[++tp].le=leng+1;l[tp].hi=p[q][i];//入棧}}int leng=0;while(tp){leng+=l[tp].le;res=max(res,leng*l[tp].hi);tp--;}//彈棧并計算return res; } int main(){ans=0;n=read(),m=read();for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){char c;cin>>c;if(c=='F') p[i][j]=p[i-1][j]+1;else p[i][j]=0;}//預處理P數組for(int i=1;i<=n;i++)//枚舉行號ans=max(ans,check(i));printf("%d\n",ans*3);return 0; }就醬qwq
轉載于:https://www.cnblogs.com/ajy-shi-cj-zui-cai/p/10386695.html
總結
以上是生活随笔為你收集整理的洛谷P4147玉某宫(最大矩阵好题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux 基础学习:文件权限与种类
- 下一篇: 迭代器和生成器的区别