悬线法
介绍
悬线法主要由up[],l[],r[]构成,其含义分别是,在某处符合题目条件的情况下,线条(抽象概念)能走到的最上边,最左边和最右边的位置。
最后统计所有子矩阵中最大的子矩阵。
1.洛谷4147玉蟾宫
点击查看代码
#include<iostream>
#include<vector>
#include<queue>
#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define ll long long
char a[1001][1001];
int up[1001][1001],l[1001][1001],r[1001][1001];
signed main()
{
cin.tie(NULL);
cout.tie(nullptr);
ios_base::sync_with_stdio(false);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
if(a[i][j]=='F')
up[i][j]=1;
l[i][j]=r[i][j]=j;
}
for(int i=1;i<=n;i++)
{
for(int j=2;j<=m;j++)
{
if(a[i][j]=='F'&&a[i][j-1]=='F')
l[i][j]=l[i][j-1];
}
for(int j=m-1;j>=1;j--)
{
if(a[i][j]=='F'&&a[i][j+1]=='F')
r[i][j]=r[i][j+1];
}
}
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]=='F'&&a[i-1][j]=='F')
{
up[i][j]=up[i-1][j]+1;
l[i][j]=max(l[i][j],l[i-1][j]);
r[i][j]=min(r[i][j],r[i-1][j]);
}
ans=max(ans,up[i][j]*(r[i][j]-l[i][j]+1));
}
}
cout<<ans*3;
return 0;
}
2.洛谷1387最大正方形
点击查看代码
#include<iostream>
#include<vector>
#include<queue>
#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define ll long long
int a[1001][1001];
int up[1001][1001],l[1001][1001],r[1001][1001];
signed main()
{
cin.tie(NULL);
cout.tie(nullptr);
ios_base::sync_with_stdio(false);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
if(a[i][j]==1)
up[i][j]=1;
l[i][j]=r[i][j]=j;
}
for(int i=1;i<=n;i++)
{
for(int j=2;j<=m;j++)
{
if(a[i][j]==1&&a[i][j-1]==1)
l[i][j]=l[i][j-1];
}
for(int j=m-1;j>=1;j--)
{
if(a[i][j]==1&&a[i][j+1]==1)
r[i][j]=r[i][j+1];
}
}
int ans=0,re=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]==1&&a[i-1][j]==1)
{
up[i][j]=up[i-1][j]+1;
l[i][j]=max(l[i][j],l[i-1][j]);
r[i][j]=min(r[i][j],r[i-1][j]);
}
re=min(up[i][j],r[i][j]-l[i][j]+1);
ans=max(ans,re);
}
}
cout<<ans;
return 0;
}
3.洛谷1169 棋盘制作
点击查看代码
#include<iostream>
#include<vector>
#include<queue>
#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define ll long long
int a[2001][2001];
int up[2001][2001],l[2001][2001],r[2001][2001];
signed main()
{
cin.tie(NULL);
cout.tie(nullptr);
ios_base::sync_with_stdio(false);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
up[i][j]=1;
l[i][j]=r[i][j]=j;
}
for(int i=1;i<=n;i++)
{
for(int j=2;j<=m;j++)
{
if(a[i][j]!=a[i][j-1])
l[i][j]=l[i][j-1];
}
for(int j=m-1;j>=1;j--)
{
if(a[i][j]!=a[i][j+1])
r[i][j]=r[i][j+1];
}
}
int ans1=0,ans2=0,re=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(i>1)
{
if(a[i][j]!=a[i-1][j])
{
up[i][j]=up[i-1][j]+1;
l[i][j]=max(l[i][j],l[i-1][j]);
r[i][j]=min(r[i][j],r[i-1][j]);
}
re=min(up[i][j],r[i][j]-l[i][j]+1);
ans2=max(ans2,up[i][j]*(r[i][j]-l[i][j]+1));
ans1=max(ans1,re*re);
} }
}
cout<<ans1<<'\n';
cout<<ans2;
return 0;
}

浙公网安备 33010602011771号