【题意】
给由01组成的矩阵,问包含1的子矩阵第二大的面积是多少
【题解】
悬线法求极大子矩阵的裸题
悬线法推荐学习博客:https://blog.csdn.net/dbc_121/article/details/77503611
【代码】
不知道怎么贴代码
#include <iostream>
#include <algorithm>
using namespace std;
const int Max = 3005;
int ves[Max][Max], up[Max][Max], Left[Max][Max], Right[Max][Max];
int temp2 = 0,mx=0;
char s[Max][Max];
int main()
{
int N, M;
scanf("%d%d",&N,&M);
for(int i=1;i<=N;++i) scanf("%s",s[i]+1);
for(int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++) {
ves[i][j]=s[i][j]-'0';
if(ves[i][j])
{
Left[i][j] = Right[i][j] = j;
up[i][j] = 1;
}
}
for (int i = 1; i <= N; i++)
for (int j = 2; j <= M; j++)
if (ves[i][j] == ves[i][j - 1]&&ves[i][j] ==1)
Left[i][j] = Left[i][j - 1]; //ÊÇ£¬Ôò
for (int i = 1; i <= N; i++)
for (int j = M - 1; j > 0; j--)
if (ves[i][j] ==ves[i][j + 1]&&ves[i][j]==1)
Right[i][j] = Right[i][j + 1];
int mx=0;
int x1,y1,x2,y2;
int l,r;
for(int i = 1;i <= N; i++)
for (int j = 1; j <= M; j++) {
if (i > 1 && ves[i][j] == ves[i - 1][j]&&ves[i][j]==1) {
Left[i][j] = max(Left[i][j], Left[i - 1][j]);
Right[i][j] =min(Right[i][j], Right[i - 1][j]);
up[i][j] = up[i - 1][j] + 1;
}
int A_instance = Right[i][j] - Left[i][j] + 1; //¼ÆË㳤¶È
int x11=i;
int y11=Left[i][j];
int x22=i-up[i][j]+1;
int y22=Right[i][j];
if(A_instance * up[i][j]>=temp2&&(x11!=x1||y11!=y1||x22!=x2||y22!=y2)){
temp2=A_instance * up[i][j];
x1=x11;
y1=y11;
x2=x22;
y2=y22;
int d1=y2-y1+1;
int d2=x1-x2+1;
mx=max(mx,temp2-d1);
mx=max(mx,temp2-d2);
//printf("i:%d j:%d temp:%d\n",i,j,temp2);
}
}
for(int i = 1;i <= N; i++)
for (int j = 1; j <= M; j++) {
int A_instance = Right[i][j] - Left[i][j] + 1; //¼ÆË㳤¶È
int x11=i;
int y11=Left[i][j];
int x22=i-up[i][j]+1;
int y22=Right[i][j];
//prin(x11,y11,x22,y22);
if(A_instance * up[i][j]>=mx&&(x11!=x1||y11!=y1||x22!=x2||y22!=y2)){
mx=A_instance * up[i][j];
//prin(x11,y11,x22,y22);
}
}
printf("%d\n",mx);
return 0;
}
【题目】
链接:https://ac.nowcoder.com/acm/contest/882/H
来源:牛客网
Given a N×MN×M binary matrix. Please output the size of second large rectangle containing all "1""1".
Containing all "1""1" means that the entries of the rectangle are all "1""1".
A rectangle can be defined as four integers x1,y1,x2,y2x1,y1,x2,y2 where 1≤x1≤x2≤N1≤x1≤x2≤N and 1≤y1≤y2≤M1≤y1≤y2≤M. Then, the rectangle is composed of all the cell (x, y) where x1≤x≤x2x1≤x≤x2 and y1≤y≤y2y1≤y≤y2. If all of the cell in the rectangle is "1""1", this is a valid rectangle.
Please find out the size of the second largest rectangle, two rectangles are different if exists a cell belonged to one of them but not belonged to the other.
输入描述:
The first line of input contains two space-separated integers N and M.
Following N lines each contains M characters cijcij.
1≤N,M≤10001≤N,M≤1000
N×M≥2N×M≥2
cij∈"01"cij∈"01"
输出描述:
Output one line containing an integer representing the answer. If there are less than 2 rectangles containning all "1""1", output "0""0".
示例1
输入
复制
1 2
01
输出
复制
0
示例2
输入
复制
1 3
101
输出
复制
1
#include <algorithm>
using namespace std;
const int Max = 3005;
int ves[Max][Max], up[Max][Max], Left[Max][Max], Right[Max][Max];
int temp2 = 0,mx=0;
char s[Max][Max];
int main()
{
int N, M;
scanf("%d%d",&N,&M);
for(int i=1;i<=N;++i) scanf("%s",s[i]+1);
for(int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++) {
ves[i][j]=s[i][j]-'0';
if(ves[i][j])
{
Left[i][j] = Right[i][j] = j;
up[i][j] = 1;
}
}
for (int i = 1; i <= N; i++)
for (int j = 2; j <= M; j++)
if (ves[i][j] == ves[i][j - 1]&&ves[i][j] ==1)
Left[i][j] = Left[i][j - 1]; //ÊÇ£¬Ôò
for (int i = 1; i <= N; i++)
for (int j = M - 1; j > 0; j--)
if (ves[i][j] ==ves[i][j + 1]&&ves[i][j]==1)
Right[i][j] = Right[i][j + 1];
int mx=0;
int x1,y1,x2,y2;
int l,r;
for(int i = 1;i <= N; i++)
for (int j = 1; j <= M; j++) {
if (i > 1 && ves[i][j] == ves[i - 1][j]&&ves[i][j]==1) {
Left[i][j] = max(Left[i][j], Left[i - 1][j]);
Right[i][j] =min(Right[i][j], Right[i - 1][j]);
up[i][j] = up[i - 1][j] + 1;
}
int A_instance = Right[i][j] - Left[i][j] + 1; //¼ÆË㳤¶È
int x11=i;
int y11=Left[i][j];
int x22=i-up[i][j]+1;
int y22=Right[i][j];
if(A_instance * up[i][j]>=temp2&&(x11!=x1||y11!=y1||x22!=x2||y22!=y2)){
temp2=A_instance * up[i][j];
x1=x11;
y1=y11;
x2=x22;
y2=y22;
int d1=y2-y1+1;
int d2=x1-x2+1;
mx=max(mx,temp2-d1);
mx=max(mx,temp2-d2);
//printf("i:%d j:%d temp:%d\n",i,j,temp2);
}
}
for(int i = 1;i <= N; i++)
for (int j = 1; j <= M; j++) {
int A_instance = Right[i][j] - Left[i][j] + 1; //¼ÆË㳤¶È
int x11=i;
int y11=Left[i][j];
int x22=i-up[i][j]+1;
int y22=Right[i][j];
//prin(x11,y11,x22,y22);
if(A_instance * up[i][j]>=mx&&(x11!=x1||y11!=y1||x22!=x2||y22!=y2)){
mx=A_instance * up[i][j];
//prin(x11,y11,x22,y22);
}
}
printf("%d\n",mx);
return 0;
}
【题目】
链接:https://ac.nowcoder.com/acm/contest/882/H
来源:牛客网
Given a N×MN×M binary matrix. Please output the size of second large rectangle containing all "1""1".
Containing all "1""1" means that the entries of the rectangle are all "1""1".
A rectangle can be defined as four integers x1,y1,x2,y2x1,y1,x2,y2 where 1≤x1≤x2≤N1≤x1≤x2≤N and 1≤y1≤y2≤M1≤y1≤y2≤M. Then, the rectangle is composed of all the cell (x, y) where x1≤x≤x2x1≤x≤x2 and y1≤y≤y2y1≤y≤y2. If all of the cell in the rectangle is "1""1", this is a valid rectangle.
Please find out the size of the second largest rectangle, two rectangles are different if exists a cell belonged to one of them but not belonged to the other.
输入描述:
The first line of input contains two space-separated integers N and M.
Following N lines each contains M characters cijcij.
1≤N,M≤10001≤N,M≤1000
N×M≥2N×M≥2
cij∈"01"cij∈"01"
输出描述:
Output one line containing an integer representing the answer. If there are less than 2 rectangles containning all "1""1", output "0""0".
示例1
输入
复制
1 2
01
输出
复制
0
示例2
输入
复制
1 3
101
输出
复制
1