题目链接:
Nanami is an expert at playing games. This day, Nanami's good friend Hajime invited her to watch a game of baseball. Unwilling as she was, she followed him to the stadium. But Nanami had no interest in the game, so she looked around to see if there was something that might interest her. That's when she saw the digital board at one end of the stadium.
The digital board is n pixels in height and m pixels in width, every pixel is either light or dark. The pixels are described by its coordinate. The j-th pixel of the i-th line is pixel (i, j). The board displays messages by switching a combination of pixels to light, and the rest to dark. Nanami notices that the state of the pixels on the board changes from time to time. At certain times, certain pixels on the board may switch from light to dark, or from dark to light.
Nanami wonders, what is the area of the biggest light block such that a specific pixel is on its side. A light block is a sub-rectangle of the board, in which all pixels are light. Pixel (i, j) belongs to a side of sub-rectangle with (x1, y1) and (x2, y2) as its upper-left and lower-right vertex if and only if it satisfies the logical condition:
Nanami has all the history of changing pixels, also she has some questions of the described type, can you answer them?
The first line contains three space-separated integers n, m and q (1 ≤ n, m, q ≤ 1000) — the height and width of the digital board, and the number of operations.
Then follow n lines, each line containing m space-separated integers. The j-th integer of the i-th line is ai, j — the initial state of pixel(i, j).
- If ai, j = 0, pixel (i, j) is initially dark.
- If ai, j = 1, pixel (i, j) is initially light.
Then follow q lines, each line containing three space-separated integers op, x, and y (1 ≤ op ≤ 2; 1 ≤ x ≤ n; 1 ≤ y ≤ m), describing an operation.
- If op = 1, the pixel at (x, y) changes its state (from light to dark or from dark to light).
- If op = 2, Nanami queries the biggest light block with pixel (x, y) on its side.
For each query, print a single line containing one integer — the answer to Nanami's query.
3 4 5
0 1 1 0
1 0 0 1
0 1 1 0
2 2 2
2 1 2
1 2 2
1 2 3
2 2 2
0
2
6
3 3 4
1 1 1
1 1 1
1 1 1
2 2 2
1 2 2
2 1 1
2 2 1
6
3
3
题意:
给一个n*m网格,每次要么变换其中一个位置,0变1或者1变0,询问的是(x,y)为一个矩形边上一点,这个矩形全部为1,最多有多少个1;
思路:
还记得以前有一个题目是矩形宽都为1,把矩形放在一起形成的区域求其中的最大矩形的面积,当时是用的单调栈,这个只是要求4次罢了;
4次分别是这个点在矩形的上下边和左右边;
然后求一个最大面积,当然这个点一定在矩形边上,那么这个点(x,y)的高度一定是最高的,两边都是依次递减的到0,我们可以把这些高排序,然后再取最大的面积就好了;
具体的看代码吧;
AC代码:
#include <bits/stdc++.h> /*#include <vector> #include <iostream> #include <queue> #include <cmath> #include <map> #include <cstring> #include <algorithm> #include <cstdio> */ using namespace std; #define Riep(n) for(int i=1;i<=n;i++) #define Riop(n) for(int i=0;i<n;i++) #define Rjep(n) for(int j=1;j<=n;j++) #define Rjop(n) for(int j=0;j<n;j++) #define mst(ss,b) memset(ss,b,sizeof(ss)); typedef long long LL; template<class T> void read(T&num) { char CH; bool F=false; for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar()); for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar()); F && (num=-num); } int stk[70], tp; template<class T> inline void print(T p) { if(!p) { puts("0"); return; } while(p) stk[++ tp] = p%10, p/=10; while(tp) putchar(stk[tp--] + '0'); putchar(' '); } const LL mod=1e9+7; const double PI=acos(-1.0); const LL inf=1e14; const int N=1e5+15; int n,m,q; int a[1005][1005],h[3][1005][1005],le[3][1005][1005],temp[1005]; void Init() { for(int j=1;j<=m;j++) { for(int i=1;i<=n;i++) { if(a[i][j])h[1][i][j]=h[1][i-1][j]+1; else h[1][i][j]=0; } for(int i=n;i>0;i--) { if(a[i][j])h[2][i][j]=h[2][i+1][j]+1; else h[2][i][j]=0; } } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(a[i][j])le[1][i][j]=le[1][i][j-1]+1; else le[1][i][j]=0; } for(int j=m;j>0;j--) { if(a[i][j])le[2][i][j]=le[2][i][j+1]+1; else le[2][i][j]=0; } } } void change (int x,int y) { a[x][y]^=1; for(int i=x;i<=n;i++)if(a[i][y])h[1][i][y]=h[1][i-1][y]+1;else h[1][i][y]=0; for(int i=x;i>0;i--)if(a[i][y])h[2][i][y]=h[2][i+1][y]+1;else h[2][i][y]=0; for(int i=y;i<=m;i++)if(a[x][i])le[1][x][i]=le[1][x][i-1]+1;else le[1][x][i]=0; for(int i=y;i>0;i--)if(a[x][i])le[2][x][i]=le[2][x][i+1]+1;else le[2][x][i]=0; } int cmp(int x,int y) { return x>y; } void solve(int x,int y) { int ans=0,l,r; for(int i=1;i<=2;i++) { temp[y]=h[i][x][y]; for(r=y+1;r<=m&&h[i][x][r];r++)if(h[i][x][r]>temp[r-1])temp[r]=temp[r-1];else temp[r]=h[i][x][r]; for(l=y-1;l>0&&h[i][x][l];l--)if(h[i][x][l]>temp[l+1])temp[l]=temp[l+1];else temp[l]=h[i][x][l]; r--;l++; sort(temp+l,temp+r+1,cmp); for(int j=l;j<=r;j++) ans=max(ans,temp[j]*(j-l+1)); temp[x]=le[i][x][y]; for(r=x+1;r<=n&&le[i][r][y];r++)if(le[i][r][y]>temp[r-1])temp[r]=temp[r-1];else temp[r]=le[i][r][y]; for(l=x-1;l>0&&le[i][l][y];l--)if(le[i][l][y]>temp[l+1])temp[l]=temp[l+1];else temp[l]=le[i][l][y]; r--;l++; sort(temp+l,temp+r+1,cmp); for(int j=l;j<=r;j++) ans=max(ans,temp[j]*(j-l+1)); } print(ans); } int main() { read(n);read(m);read(q); Riep(n)Rjep(m)read(a[i][j]); int flag,x,y; Init(); while(q--) { read(flag);read(x);read(y); if(flag==1)change(x,y); else solve(x,y); } return 0; }