W tym PDF na stronie 87 jest treść zadania i jego rozwiązanie https://oi.edu.pl/static/attachment/20110811/oi9.pdf
próbowałem napisać rozwiązanie w Pythnonie, bo nie do końca rozumiem co tam się dzieje

#!/bin/python3
def update_G(G, n):
    for j in range(1, n + 1):
        for i in range(1, n + 1):
            if G[i][j] == 1:
                G[i][j] = 0
            else:
                G[i][j] = G[i-1][j] + 1
                
Kandydat = 0

def przetworz_wiersz(G, n):
    global Kandydat
    stos = []
    g = 0
    for i in range(1, n + 1):
        byl_pop = False
        if not len(stos) == 0:
            k, g = stos[-1][0], stos[-1][1]
        while not len(stos) == 0 and g > G[i]:
            Kandydat = max(Kandydat, (i - k) * G[i])
            kp, gp = stos.pop() #k', g'
            byl_pop = True
            if not len(stos) == 0:
                k, g = stos[-1]
        if (len(stos) == 0 and G[i] > 0) or g < G[i]:
            if byl_pop:
                stos.append((kp, G[i]))
            else:
                stos.append((i, G[i]))
            

def main():
    n = int(input())
    G = [[0 for i in range(n + 2)] for j in range(n + 2)]

    for i in range(1, n + 1):
        for j, val in enumerate(list(map(int, input().split()))):
            G[i][j+1] = val

    update_G(G, n)

    for i in G:
        print(i)

    for wiersz in G:
        przetworz_wiersz(wiersz, n)

    print(Kandydat)
main()

No i dla przykładowych danych daje błędny wynik, a jak sprawdzałem w debuggerze dla danych z rozwiązania to stos miał te same wartości jak w rozwiązaniu, proszę o pomoc :D

EDIT:
Problem rozwiązany, pole powinno liczyć się ze wzoru (i - k) * g, jak było opisane, prawdopodobnie pisząc pseudokod zdarzyła się pomyłka. taki kod przechodzi na 100 pkt:

#include <bits/stdc++.h>

using namespace std;

const int MAX_GARDEN_SIZE = 2e3 + 7;
vector<vector<int>> garden(MAX_GARDEN_SIZE, vector<int>(MAX_GARDEN_SIZE));
int max_area = 0;

void load_garden(int n){
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= n; j++){
			cin >> garden[i][j];
		}
	}
}

void make_pref_of_columns(int n){
	for (int j = 1; j <= n; j++){
		for (int i = 1; i <= n; i++){
			if (garden[i][j] == 1)
				garden[i][j] = 0;
			else
				garden[i][j] = garden[i-1][j] + 1;
		}
	}
}

void process_line(vector<int> & G, int n){
	stack<pair<int, int>> s;
	int g, k, gp, kp;
	g = 0;
	for (int i = 1; i <= n + 1; i++){
		bool was_pop = false;
		
		if (!s.empty()){
			k = s.top().first; g = s.top().second;
		}
		
		while (!s.empty() && g > G[i]){
			max_area = max(max_area, (i - k) * g);
			kp = s.top().first; g = s.top().second;
			s.pop(); 
			was_pop = true;
			if (! s.empty()){
				k = s.top().first; g = s.top().second;
			}
		}
		
		if ((s.empty() && G[i] > 0) || g < G[i]){
			if(was_pop)
				s.push(make_pair(kp, G[i]));
			else
				s.push(make_pair(i, G[i]));
		}
	}
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(NULL);
	
	int n;
	cin >> n;

	load_garden(n);

	make_pref_of_columns(n);

	for (auto line : garden)
		process_line(line, n);
	
	cout << max_area << "\n";

	return 0;
}