题目:
题目思路
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;
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 ;
}