hdu 1505 1506 2870 2830 最大子矩阵面积

版权声明:欢迎转载,转载请注明出处,如有错误,还望指出,谢谢 博客地址:https://blog.csdn.net/lanyanzhiji123asd https://blog.csdn.net/lanyanzhiji123asd/article/details/87508229

题目链接

1505  http://acm.hdu.edu.cn/showproblem.php?pid=1505

1506  http://acm.hdu.edu.cn/showproblem.php?pid=1506

2807  http://acm.hdu.edu.cn/showproblem.php?pid=2870

2830  http://acm.hdu.edu.cn/showproblem.php?pid=2830

这些题都是求最大子矩阵面积

首先求出每个数连续的高

这个比较简单

通过不停的迭代l , r数组

然后求出这个点左右两边可扩展到的宽度

l , r 数组记录着这个点分别在左边和右边连续的起点和终点

最后求出面积

1505

#include<bits/stdc++.h>
using namespace std;
#define ll long long int
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
int mp[1005][1005],l[1005],r[1005];
int main()
{
	std::ios::sync_with_stdio(false);
	int t,i,j;
	cin>>t;
	while(t--)
	{
		int n,m;
		cin>>m>>n;
		memset(mp,0,sizeof(mp));
		for(i=1;i<=m;i++)
		{
			for(j=1;j<=n;j++)
			{
				char ch;
				cin>>ch;
				if(ch=='F')
					mp[i][j]=mp[i-1][j]+1;
				else mp[i][j]=0;
			}
		}
		int ans=-INF;
		for(i=1;i<=m;i++)
		{
			memset(l,0,sizeof(l));
			memset(r,0,sizeof(r));
			for(j=1;j<=n;j++)
				l[j]=r[j]=j;
			l[0]=1;
			r[n+1]=n;
			mp[i][0]=mp[i][n+1]=-1;
			for(j=1;j<=n;j++)
			{
				while(mp[i][l[j]-1]>=mp[i][j])
					l[j]=l[l[j]-1];
			}
			for(j=n;j>=1;j--)
			{	
				while(mp[i][r[j]+1]>=mp[i][j])
				{
//					cout<<"qqq    "<<r[j]<<"  "<<j<<"   "<<mp[i][r[j]+1]<<"    "<<mp[i][r[j]]<<endl;
					r[j]=r[r[j]+1];
				}
					
			}
		
			for(j=1;j<=n;j++)
			{
				if(mp[i][j]*(r[j]-l[j]+1)>ans)
					ans=mp[i][j]*(r[j]-l[j]+1);
			}
		}
		cout<<ans*3<<endl;
	 } 

	return 0;
} 

1506

#include<bits/stdc++.h>
using namespace std;
#define ll long long int
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
ll mp[100005],l[100005],r[100005];
int main()
{
	std::ios::sync_with_stdio(false);
	int i,j;ll n;
	
	while(cin>>n&&n)
	{
		memset(mp,0,sizeof(mp));
		for(i=1;i<=n;i++)
		{
			cin>>mp[i];
		}
		ll ans=-INF;
		for(j=1;j<=n;j++)
			l[j]=r[j]=j;
		l[0]=1;
		r[n+1]=n;
		mp[0]=mp[n+1]=-1;
		for(j=1;j<=n;j++)
		{
			while(mp[l[j]-1]>=mp[j])
				l[j]=l[l[j]-1];
		}
		for(j=n;j>=1;j--)
		{	
			while(mp[r[j]+1]>=mp[j])
			{
//					cout<<"qqq    "<<r[j]<<"  "<<j<<"   "<<mp[i][r[j]+1]<<"    "<<mp[i][r[j]]<<endl;
				r[j]=r[r[j]+1];
			}
				
		}
	
		for(j=1;j<=n;j++)
		{
			if(mp[j]*(r[j]-l[j]+1)>ans)
				ans=mp[j]*(r[j]-l[j]+1);
		}
		cout<<ans<<endl;
	 } 

	return 0;
} 

2870

#include<bits/stdc++.h>
using namespace std;
#define ll long long int
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
char mp[1005][1005];
int a[1005][1005],b[1005][1005],c[1005][1005],l[1005],r[1005];

int main()
{
	std::ios::sync_with_stdio(false);
	int n,m,i,j;
	while(~scanf("%d%d",&m,&n))
	{
		memset(mp,0,sizeof(mp));
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		memset(c,0,sizeof(c));
		for(i=1;i<=m;i++)
		{//	cout<<"qqq"<<endl;
			scanf("%s",mp[i]+1);
		}
			
	
		for(i=1;i<=m;i++)
		{
			for(j=1;j<=n;j++)
			{
				if(mp[i][j]=='w'||mp[i][j]=='y'||mp[i][j]=='z'||mp[i][j]=='a')
					a[i][j]=a[i-1][j]+1;
				else a[i][j]=0;
				if(mp[i][j]=='w'||mp[i][j]=='x'||mp[i][j]=='z'||mp[i][j]=='b')
					b[i][j]=b[i-1][j]+1;
				else b[i][j]=0;
				if(mp[i][j]=='x'||mp[i][j]=='y'||mp[i][j]=='z'||mp[i][j]=='c')
					c[i][j]=c[i-1][j]+1;
				else c[i][j]=0;
			}
		}
		
		int ans=-INF;
		for(i=1;i<=m;i++)
		{
			memset(l,0,sizeof(l));
			memset(r,0,sizeof(r));
			for(j=1;j<=n;j++)
				l[j]=r[j]=j;
			l[0]=1;
			r[n+1]=n;
			a[i][0]=a[i][n+1]=-1;
			for(j=1;j<=n;j++)
			{
				while(a[i][l[j]-1]>=a[i][j])
					l[j]=l[l[j]-1];
			}
			for(j=n;j>=1;j--)
			{	
				while(a[i][r[j]+1]>=a[i][j])
				{
//					cout<<"qqq    "<<r[j]<<"  "<<j<<"   "<<mp[i][r[j]+1]<<"    "<<mp[i][r[j]]<<endl;
					r[j]=r[r[j]+1];
				}
					
			}
		
			for(j=1;j<=n;j++)
			{
				if(a[i][j]*(r[j]-l[j]+1)>ans)
					ans=a[i][j]*(r[j]-l[j]+1);
			}
		}
		
		for(i=1;i<=m;i++)
		{
			memset(l,0,sizeof(l));
			memset(r,0,sizeof(r));
			for(j=1;j<=n;j++)
				l[j]=r[j]=j;
			l[0]=1;
			r[n+1]=n;
			b[i][0]=b[i][n+1]=-1;
			for(j=1;j<=n;j++)
			{
				while(b[i][l[j]-1]>=b[i][j])
					l[j]=l[l[j]-1];
			}
			for(j=n;j>=1;j--)
			{	
				while(b[i][r[j]+1]>=b[i][j])
				{
//					cout<<"qqq    "<<r[j]<<"  "<<j<<"   "<<mp[i][r[j]+1]<<"    "<<mp[i][r[j]]<<endl;
					r[j]=r[r[j]+1];
				}
					
			}
		
			for(j=1;j<=n;j++)
			{
				if(b[i][j]*(r[j]-l[j]+1)>ans)
					ans=b[i][j]*(r[j]-l[j]+1);
			}
		}
		
		for(i=1;i<=m;i++)
		{
			memset(l,0,sizeof(l));
			memset(r,0,sizeof(r));
			for(j=1;j<=n;j++)
				l[j]=r[j]=j;
			l[0]=1;
			r[n+1]=n;
			c[i][0]=c[i][n+1]=-1;
			for(j=1;j<=n;j++)
			{
				while(c[i][l[j]-1]>=c[i][j])
					l[j]=l[l[j]-1];
			}
			for(j=n;j>=1;j--)
			{	
				while(c[i][r[j]+1]>=c[i][j])
				{
//					cout<<"qqq    "<<r[j]<<"  "<<j<<"   "<<mp[i][r[j]+1]<<"    "<<mp[i][r[j]]<<endl;
					r[j]=r[r[j]+1];
				}
					
			}
		
			for(j=1;j<=n;j++)
			{
				if(c[i][j]*(r[j]-l[j]+1)>ans)
					ans=c[i][j]*(r[j]-l[j]+1);
			}
		}
		cout<<ans<<endl;
	}

	return 0;
} 

2830

这个有一个条件就是列可以互换

我们遍历每行

求出当前行 为行尾时每列1的最大数

再求面积

scanf printf   和cout cin不要混用    用了scanf printf 也不要开同步

不然会WA

#include<bits/stdc++.h>
using namespace std;
#define ll long long int
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
char mp[1005][1005];
int a[1005],num[1005];

bool cmp(int a,int b)
{
	return a>b;
}

int main()
{
//	std::ios::sync_with_stdio(false);
	int n,m,i,j;
	while(cin>>n>>m)
	{
		memset(a,0,sizeof(a));
		memset(num,0,sizeof(num));
		int ans=-INF;
		for(i=1;i<=n;i++)
		{
			scanf("%s",mp[i]+1);
		}
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=m;j++)
			{
				if(mp[i][j]=='1')
				{
					num[j]++;
				}
				else num[j]=0;
//				cout<<a[j]<<endl;
				a[j]=num[j];
			}
		
			sort(a+1,a+m+1,cmp);
		
			for(j=1;j<=m;j++)
			{
				ans=max(a[j]*j,ans);
//				cout<<a[j]<<"   "<<j<<endl;
			}
		}
		printf("%d\n",ans);
	} 

	return 0;
} 

猜你喜欢

转载自blog.csdn.net/lanyanzhiji123asd/article/details/87508229
今日推荐