1. 程式人生 > >[POJ1964]City Game (懸線法)

[POJ1964]City Game (懸線法)

bsp cond logs namespace csdn info tail pair com

技術分享圖片

題意

其實就是BZOJ3039 不過沒權限號(粗鄙之語)

同時也是洛谷4147

就是求最大子矩陣然後*3

思路

懸線法

有個博客講的不錯https://blog.csdn.net/u012288458/article/details/48197727

GREED-VI大佬之前也講過,友鏈一下https://www.cnblogs.com/GREED-VI/p/9887399.html (他說的其實是懸線法,掃描線和這個不一樣的吧)

代碼

水水水

#include<cstdio>
#include<iostream>
#include<cstring> 
#include
<algorithm> #define N 1005 using namespace std; int n,m; int ans; int up[N][N],L[N][N],R[N][N]; pair<int,int> st[N]; bool v[N][N],f_fall; void init() { char ch; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>ch; v[i][j]
=(ch==F?1:0); if(v[i][j]) f_fall=1; } } void solve() { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(!v[i][j]) up[i][j]=0; else up[i][j]=up[i-1][j]+1; for (int i=1;i<=n;i++) { int top=0; st[++top]=make_pair(-1
,0); for (int j=1;j<=m;j++) { while (up[i][j]<=st[top].first) top--; L[i][j]=j-st[top].second-1; st[++top]=make_pair(up[i][j],j); } } for (int i=1;i<=n;i++) { int top=0; st[++top]=make_pair(-1,m+1); for (int j=m;j>=1;j--) { while (up[i][j]<=st[top].first) top--; R[i][j]=st[top].second-j-1; st[++top]=make_pair(up[i][j],j); } } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ans=max(ans,(L[i][j]+R[i][j]+1)*up[i][j]); ans*=3; } int main() { //freopen("cpp.in","r",stdin); //freopen("cpp.out","w",stdout); int Q;scanf("%d",&Q); while(Q--) { f_fall=0; init(); if(f_fall==0) printf("0\n"); else{ solve(); printf("%d\n",ans); ans=0; memset(v,0,sizeof(v)); memset(up,0,sizeof(up)); memset(L,0,sizeof(L)); memset(R,0,sizeof(R)); memset(st,0,sizeof(st)); } } return 0; }

[POJ1964]City Game (懸線法)