求极大全1矩阵个数
派大星有一个n*m的的矩阵。
定义全1子矩阵:为仅包含 0和1的子矩阵。
定义极大全 矩阵:
- 首先该矩阵是全 矩阵。
- 其次该矩阵不是其它某个全 矩阵的子矩阵。
派大星想知道它的矩阵中包含多少个极大全1 矩阵。
思路:
类似题目,演算法笔记上引出的问题是求面积最大的全1矩阵,这道题类似做法,在处理最大矩阵的过程中,判断当前的这个矩阵是否会被包含在后续求出来的矩阵中,假设在当前的行处理出最大的矩阵,那么要在知道会不会被包含在下一行的矩阵中,只要知道当前这一行,这个矩阵的对应的1位置,如果下一行中也全为1,那么一定会被包含,如果下一行中对应位置中有一个位置为0,那么说明这个矩阵不会被包含在下一行的最大矩阵中。做法和求面积最大全1矩阵一样,加个这个判断包含关系就行。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
typedef vector<int>vi;
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define fi first
#define se second
#define de(x) cout<<#x<<"="<<x<<endl;
#define dd(x) cout<<#x<<"="<<x<<" " ;
#define pb(x) push_back(x)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N=5e3+5;
char mp[N][N];
int h[N][N];
int area[N][N];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;++i){
scanf("%s",mp[i]+1);
}
memset(h,0,sizeof(h));
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(mp[i][j]=='1'){
h[i][j]=h[i-1][j]+1;
}
int ans=0;
for(int i=1;i<=n;++i){
stack<pii>stk;
int ma=-1;
for(int j=1;j<=m+1;++j){
int pos=j;
while(!stk.empty()&&stk.top().fi>h[i][j]){
if(stk.top().se<=ma){
ans++;
}
pos=stk.top().se;
stk.pop();
}
if(!h[i+1][j])ma=j;
if(h[i][j]&&(stk.empty()||(stk.top().fi<h[i][j])))
stk.push(pii(h[i][j],pos));
}
}
cout<<ans<<endl;
return 0;
}
求面积最大
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
typedef vector<int>vi;
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define fi first
#define se second
#define de(x) cout<<#x<<"="<<x<<endl;
#define dd(x) cout<<#x<<"="<<x<<" " ;
#define pb(x) push_back(x)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N=1e2+5;
char mp[N][N];
int wl[N][N];
int main()
{
int t;
cin>>t;
int n,m,q;
while(t--){
cin>>n>>m>>q;
rep(i,1,n+1)
scanf("%s",mp[i]+1);
memset(wl,0,sizeof(wl));
rep(i,1,n+1)
rep(j,1,m+1){
if(mp[i][j]==mp[i][j-1])wl[i][j]=wl[i][j-1]+1;
else wl[i][j]=1;
}
cout<<n<<" "<<m<<" "<<q<<endl;
while(q--){
int r,c;
cin>>r>>c;
r++;
c++;
int ma=min(m,n);
int ans=1;
for(int i=1;i<=ma;++i){
if(r+i>n||r-i<1||c+i>m||r-i<1)
break;
bool f=false;
for(int j=r-i;j<=r+i;++j){
if(mp[j][c+i]!=mp[r][c]||wl[j][c+i]<i*2+1){
f=true;
break;
}
}
if(!f)ans=i*2+1;
else break;
}
cout<<ans<<endl;
}
}
return 0;
}