/*
Problem link Type: DP, data structure Algorithm: I use the stack in the problem, with this I can solve it in O(n^2) Let h[i][j] be the height of the consecutive comlumn of 0 at (i,j) Let l[i][j] is the index left most element of (i,j) that from h[i][l[i][j]] to h[i][j] is all >= h[i][j] Let r[i][j] is the index right most element of (i,j) that from h[i][j] to h[i][r[i][j]] is all >= h[i][j] Find max of (j-l[i][j]+r[i][j]-j+1)*h[i][j] for all i,j l and r are calculated in O(n^2) by using the stack */ #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> using namespace std; const int maxn = 110; //------------------------------ class Stack { public: int val[maxn]; int top; Stack () { top = 0; } void push(int value) { val[++top] = value; } int pop() { return(val[top--]); } }; //------------------------------ int a[maxn][maxn],h[maxn][maxn],r[maxn][maxn],l[maxn][maxn]; int n,b; //------------------------------ void readfile() { cin >> n; cin >> b; memset(a,0,sizeof(a)); for (int i=1; i<=b; i++) { int r1,c1,r2,c2; cin >> r1 >> c1 >> r2 >> c2; for (int u = r1; u<=r2; u++) for (int v = c1; v<=c2; v++) a[u][v] = 1; } for (int i=1; i<=n; i++) for (int j=1; j<=n; j++) if (a[i][j]==0) { if (a[i-1][j]==0) h[i][j] = h[i-1][j]+1; else h[i][j] = 1; } else h[i][j] = 0; } //------------------------------ void FindRight() { for (int i=1; i<=n; i++) { Stack st; r[i][n] = n; st.push(n); for (int j=n-1; j>=1; j--) { r[i][j] = j; int tmp = j; while (st.top>0 && h[i][j]<=h[i][st.val[st.top]]) tmp = st.pop(); r[i][j] = r[i][tmp]; st.push(j); } } } //------------------------------ void FindLeft() { for (int i=1; i<=n; i++) { Stack st; l[i][1] = 1; st.push(1); for (int j=2; j<=n; j++) { l[i][j] = j; int tmp = j; while (st.top>0 && h[i][j]<=h[i][st.val[st.top]]) tmp = st.pop(); l[i][j] = l[i][tmp]; st.push(j); } } } //------------------------------ int solve() { FindRight(); FindLeft(); int result = 0; for (int i=1; i<=n; i++) for (int j=1; j<=n; j++) if (((r[i][j]-j+1)+(j-l[i][j]))*h[i][j] > result) result = ((r[i][j]-j+1)+(j-l[i][j]))*h[i][j]; return(result); } //------------------------------ int main() { int ntest; cin >> ntest; for (int test=1; test<=ntest; test++) { readfile(); cout << solve() << endl; } return 0; } //------------------------------
Introduction
This is my blog of programming, I take notes and leave codes of computer science problems I solved here. Be my guest to comment :)
Thursday, November 15, 2012
uva 10667 - Largest Block
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment