面積最大的全1子矩陣 九度OJ 1497

2022-02-21 10:46:34 字數 2024 閱讀 3097

題目描述:在乙個m * n的矩陣中,所有的元素只有0和1,從這個矩陣中找出乙個面積最大的全1子矩陣,所謂最大是指元素1的個數最多。

輸入:輸入可能包含多個測試樣例。

對於每個測試案例,輸入的第一行是兩個整數m、n(1<=m、n<=1000):代表將要輸入的矩陣的大小。

矩陣共有m行,每行有n個整數,分別是0或1,相鄰兩數之間嚴格用乙個空格隔開。

輸出:對應每個測試案例,輸出矩陣中面積最大的全1子矩陣的元素個數。

樣例輸入:

2 2

0 00 0

4 40 0 0 0

0 1 1 0

0 1 1 0

0 0 0 0

樣例輸出:0 4解題思路:**自

方法是:

1、先將0/1矩陣讀入x,對每乙個非零元素x[i][j],將其更新為:在本行,它前面的連續的1的個數+1(+1表示算入自身)

比如,若某一行為0 1 1 0 1 1 1,則更新為0 1 2 0 1 2 3

2、對每乙個非零元素x[i][j],在第j列向上和向下掃瞄,直到遇到比自身小的數,若掃瞄了y行,則得到乙個大小為x[i][j]*(y+1)的全1子矩陣(+1表示算入自身所在行)

比如,若某一列為[0 3 4 3 5 2 1]'(方便起見,這裡將列表示成乙個列向量),我們處理這一列的第4個元素,也就是3,它向上可以掃瞄2個元素,向下可以掃瞄1個元素,於是得到乙個4×3的全1子矩陣。

3、在這些數值中取乙個最大的。

思想大概如下圖所示(空白處的0沒有標出)

對照步驟2中給出的例子,藍色的箭頭表示向上向下掃瞄,黑色的框表示最終得到的全1子矩陣

這樣做為什麼是對的?

想一想,對那個最大的全1子矩陣,用這種方法能不能找到它呢?——肯定可以。

乙個最大全1子矩陣,肯定是四個邊界中的每乙個都不能再擴充套件了,如下圖

假設圖中全1子矩陣就是最大子矩陣,則左邊界左側那一列肯定有乙個或多個0(否則就可以向左邊擴充套件一列,得到乙個更大的全1矩陣)

對其他3個邊界有類似的情況。

然後看圖中用黑圈標出的1(其特點是:和左邊界左側的某個0在同一行),從這個1出發,按照之前的方法,向上向下掃瞄,就可以得到這個子矩陣。所以,肯定可以找到。

下面是我的**,實際實現的時候,為了提高效率,估計了一下upperbound,這個upperbound就是:在當前列,

包含x[i][col]的連續的非零序列的和,比如對某列[0 3 4 3 5 2 1]',後面6個的upperbound都是

3 + 4 + 3 + 5 + 2 + 1 = 18,對於0元素,不需要upperbound

1 #include2

using

namespace

std;34

intmain()517

}18//prepare:

19for(int i=0;i)23}

24//

計算upperbound

25for(int j=0;j)

34for(int k=i;k)

37 i=temp;38}

39} 40}

4142

int maxarea=0;43

for(int i=0;i)

52for(int row=i+1;row)

57if(cnt*val>maxarea)maxarea=cnt*val;58}

59}60}

61 cout<

63return0;

6465 }

view code

九度 1497 面積最大的全1子矩陣

題目描述 在乙個m n的矩陣中,所有的元素只有0和1,從這個矩陣中找出乙個面積最大的全1子矩陣,所謂最大是指元素1的個數最多 leetcode 原題,沒有案例就是跪,wa 到沒脾氣 未通過九度測試 include include include include include using names...

面積最大的全1子矩陣

題目描述 在乙個m n的矩陣中,所有的元素只有0和1,從這個矩陣中找出乙個面積最大的全1子矩陣,所謂最大是指元素1的個數最多。輸入 輸入可能包含多個測試樣例。對於每個測試案例,輸入的第一行是兩個整數m n 1 m n 1000 代表將要輸入的矩陣的大小。矩陣共有m行,每行有n個整數,分別是0或1,相...

ACM整理(四) 1497面積最大的全1子陣

程式設計思想 本質為計算直方圖中最小長方形面積 設立三個陣列,h,l,r 陣列h i 代表從當前行向上的直方圖的第i列有多少個1,有0間隔即不算 陣列l i 代表大於等於h i 個1的列最小標號為多少 陣列r i 代表大於等於h i 個1的列最大標號為多少 算完這三個陣列之後,迴圈j次 用公式h i...