poj1964最大子矩陣 (單調棧加列舉)
阿新 • • 發佈:2019-02-17
題目大意:
一個矩陣中,求F組成的矩陣的面積,(答案乘以三)。
思路:n如果是小於100的,就可以通過字首和,然後三重迴圈暴力找,和poj1050很像,但由於是1000,就不可以了,時間複雜度太高。
這道題的類別是單調棧,仔細想一下,發現其實就是先統計每一行網上有多少個長方形,然後再列舉每一行,算出最大的maxx,相當於poj2559的加強版。程式碼有很多細節要注意,最大的坑是,輸入的圖,兩個符號之間不一定只有一個空格,所以每一個字元都要用%s輸入,對拍拍了好久都不知道錯哪裡,看了題解才發現,(最難受的是看的最多的人的題解還是錯的)辣雞題目,浪費我時間。
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<string> #include<math.h> #include<cmath> #include<time.h> #include<map> #include<set> #include<vector> #include<queue> #include<algorithm> #include<numeric> #include<stack> using namespace std; const int maxn=1010; char mp[maxn][maxn]; int n,m,u[maxn][maxn]; struct dian{ int r,h; }; int main(){ int t; cin>>t; stack<dian>s; while(t--){ memset(u,0,sizeof(u)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%s",mp[i]); if(mp[i][0]=='F'){ u[i][j]=u[i-1][j]+1; }else{ u[i][j]=0; } } } int maxx=0; int r; for(int i=1;i<=n;i++){ while(!s.empty())s.pop(); for(int j=1;j<=m+1;j++){ dian a,b; r=0; if(s.empty()){ a.h=u[i][j]; a.r=1; s.push(a); continue; } a=s.top(); if(u[i][j]>=a.h){ b.h=u[i][j]; b.r=1; s.push(b); } else{ r=0; while(a.h>u[i][j]&&!s.empty()){ a=s.top(); r+=a.r; int h=a.h; s.pop(); maxx=max(maxx,h*r); if(!s.empty()) a=s.top(); } a.r=r+1; a.h=u[i][j]; s.push(a); } } } printf("%d\n",3*maxx); } }