A - 最大矩形单调栈解法(Week5作业)

题目:

在这里插入图片描述在这里插入图片描述

题目思路

1、是一道经典的单调栈问题;
2、利用单调栈计算出当前高度的矩形左右两边可以延伸到的宽度
	·计算出当前矩形左边第一个比该矩形高度小的坐标
	·计算出当前矩形右边第一个比该矩形高度小的坐标
	·两者之差,是以当前矩形高度为高的最大矩形的宽度
	·计算矩形面积,求出最大面积
3、利用一个单调栈从左往右对矩形高度进行遍历
	·如果当前矩形高度大于栈顶的矩形高度,压入栈,宽度(坐标)加一
	·否则,将单调栈中的矩形弹出,并根据弹出矩形高度算当前面积,记录最大值

解题中遇到的问题

(这个题目我遇到了许多从来没有遇到过得“玄学”问题)改到爆炸,最后才发现居然有这么多细节没有注意到。
第一种思路中:
1、term、st、record、recordr等数组没有申请全局变量  ---------wa 或 re
这个问题真的不应该再出现,一定要记住,主函数申请的数组有空间限制,没有确定数组数量一定较小的,都申请全局变量
2、ans设为int型,导致答案数据溢出 -------wa
没有看到数据范围,导致一直发现不了为什么会wa,下次写题一定要注意数据范围
3、long long z = int a*b  依然会导致数据溢出,没有强制转换类型-------wa
应该改为long long z=(long long ) a*b(其中a、b为int型)
第二种思路中:
同样没有申请全局变量数组,导致wa,而且发现这种情况下oj系统输出和本地跑出的数据是不一样的!

AC代码

第一种思路:

#include<iostream>
#include<stdio.h>
#include<cstring> 
#include<algorithm>
using namespace std;
int term[1000005];
int st[1000010],record[1000010],recordr[1000010];
long long ans;
int main()
{
	int n;
	//freopen("a.txt","r",stdin);
	while(scanf("%d",&n)&&n)
	{
		memset(term, 0, sizeof(term));
		memset(record, 0, sizeof(record));
		memset(recordr, 0, sizeof(recordr));
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&term[i]);
			record[i]=i+1;
			recordr[i]=i;
		}
		int st[n+1],top=-1;
		int index[n+1];
		for(int i=1;i<=n+1;i++)
		{
			while(top>-1&&st[top]>term[i])
			{
				record[index[top]]=i;
				top--;
			}
			st[++top]=term[i];
			index[top]=i;
		}
		int str[n+1];
		top=-1;
		int indexr[n+1];
		for(int i=n;i>-1;i--)
		{
			while(top>-1&&str[top]>term[i])
			{
				recordr[indexr[top]]=i+1;
				top--;
			}
			str[++top]=term[i];
			indexr[top]=i;
		}
		ans=0;
		for(int j=1;j<=n;j++)
		{
			ans=max((long long)term[j]*(record[j]-recordr[j]),ans);
		}
		cout<<ans<<endl;
	}
	return 0;
}

第二种思路

#include<iostream>
#include<cstring>
using namespace std;
int term[1000005];
int st[1000010],record[1000010];
long long ans;
int main()
{
	int n;
	while(cin>>n&&n)
	{
		memset(term, 0, sizeof(term));
		memset(st, 0, sizeof(st));
		memset(record, 0, sizeof(record));
		ans = 0;
		for(int i=1;i<n+1;i++) cin>>term[i];
		long long p=0;
		for(int i=1;i<=n+1;i++)
		{
			if(term[i]>st[p])
			{
				st[++p]=term[i];
				record[p]=1;
			}
			else
			{
				int w=0;
				while(p>0&&st[p]>term[i])
				{
					w+=record[p];
					long long z=(long long)w*st[p];
					if(ans<z) ans=z;
					p--; 
				}
				st[++p]=term[i];
				record[p]=w+1;
			} 
		}
		cout<<ans<<endl;
	}
	return 0;
}
发布了24 篇原创文章 · 获赞 9 · 访问量 7171

猜你喜欢

转载自blog.csdn.net/qq_40103496/article/details/104966401