Largest Submatrix of All 1’s(思維+單調棧)

weixin_30924079發表於2020-04-04

Given a m-by-n (0,1)-matrix, of all its submatrices of all 1’s which is the largest? By largest we mean that the submatrix has the most elements.

Input

The input contains multiple test cases. Each test case begins with m and n (1 ≤ mn ≤ 2000) on line. Then come the elements of a (0,1)-matrix in row-major order on mlines each with n numbers. The input ends once EOF is met.

Output

For each test case, output one line containing the number of elements of the largest submatrix of all 1’s. If the given matrix is of all 0’s, output 0.

Sample Input

2 2
0 0
0 0
4 4
0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0

Sample Output

0
4 

題意:

找最大的為1的子矩陣,

一開始的錯誤程式碼:H是表示他的連續高度,L和R是左邊第一個比他小的座標和右邊比他小的座標,這個過程都是單調棧維護的,

然後暴力列舉最大的點,但是這樣有錯誤,就是L到R這個區間內H的值不一定是相同的

錯誤程式碼:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<vector>
#include<cmath>

const int maxn=1e5+5;
typedef long long ll;
using namespace std;
int n,m;
int Map[2005][2005];
int H[2005][2005];
int L[2005][2005];
int R[2005][2005];
int  main()
{
	std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    while(cin>>n>>m)
    {
    	for(int t=1;t<=n;t++)
    	{
    		for(int j=1;j<=m;j++)
    		{
    			scanf("%d",&Map[t][j]);
			}
		}
		for(int t=1;t<=n;t++)
		{
			for(int j=1;j<=m;j++)
			{
				if(Map[t][j]==1)
				{
					H[t][j]=1;
				 } 
				 else
				 {
				 	H[t][j]=0;
				 }
			}
		}
		memset(L,0,sizeof(L));
		for(int t=1;t<=n;t++)
		{
			for(int j=1;j<=m;j++)
			{
				R[t][j]=m+1;
			}
		}
		for(int t=2;t<=n;t++)
		{
			for(int j=1;j<=m;j++)
		    {
		    	if(H[t-1][j]!=0&&H[t][j]==1)
		    	{
		    		H[t][j]=H[t-1][j]+1;
				}
		    }
		}
	    for(int t=1;t<=n;t++)
	    {
	    	stack<int>S1;
	    	for(int j=1;j<=m;j++)
	    	{
	    		  while(S1.size() && Map[t][S1.top()]>=Map[t][j]) S1.pop();
                  if(S1.empty())    L[t][j]= 0;
                  else   L[t][j] = S1.top();
                  S1.push(j);
			}
		}
		 for(int t=1;t<=n;t++)
	    {
	    	stack<int>S1;
	    	for(int j=m;j>=1;j--)
	    	{
	    		  while(S1.size() && Map[t][S1.top()]>=Map[t][j]) S1.pop();
                  if(S1.empty())     R[t][j]= m+1;
                  else               R[t][j] = S1.top();
                  S1.push(j);
			}
		}
		int manxx=0;
		
		for(int t=1;t<=n;t++)
		{
			
			for(int j=1;j<=m;j++)
			{
			    if(H[t][R[t][j]-1]==H[t][L[t][j]+1])  
				manxx=max(manxx,H[t][j]*(R[t][j]-L[t][j]-1));
			}
		}
		cout<<manxx<<endl;
	}
    return 0;
}

AC程式碼:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<cmath>
const int maxn=2e5+5;
typedef long long ll;
using namespace std;
int H[2005];
int a[2005];
int main()
{
   	std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    int n,m,x,top,tmp,maxnxx;
    stack<int>S1; 
    while(cin>>n>>m)  
    {  
        maxnxx=0;  
        memset(H,0,sizeof(H)); 
        for(int t=0;t<n;t++)  
        {  
            for(int j=1;j<=m;j++)  
            {  
                scanf("%d",&x); 
                if(x==1) H[j]=H[j]+1;    
                else H[j]=0;
                a[j]=H[j]; 
            }  
            a[m+1]=-1; 
            for(int j=1;j<=m+1;j++)  
            {  
                if(S1.empty()||a[j]>=a[S1.top()])  
                { 
                    S1.push(j);  
                }  
                else  
                {  
                    while(!S1.empty()&&a[j]<a[S1.top()])  
                    {    
                        top=S1.top();  
                        S1.pop();  
                        tmp=(j-top)*a[top]; 
                        if(tmp>maxnxx) maxnxx=tmp; 
                    }  
                    S1.push(top);    
                    a[top]=a[j]; 
                }  
            }  
        }  
        cout<<maxnxx<<endl; 
    }
   return 0;
}

 

 

轉載於:https://www.cnblogs.com/Staceyacm/p/10781765.html

相關文章