题目描述
题目分析
这道题的解题思路是用每个方条的顶点向两端看齐,计算其面积(类似于木桶原理),维护一个最大的ans。
具体实现使用单调栈,首先把元素存入store[],然后依次遍历store[],若store[i]大于等于栈顶元素,就使其入栈,同时利用width[top]标记其宽度为1,维护一个递减栈;若store[i]小于栈顶元素,依次出栈找到最近一个小于store[i]的元素,在这期间维护ans=最大的width * stack[top]。
需要注意的是,在循环结束后,栈中可能仍然剩余元素,此时需要依次使其出栈并维护ans(因为可能出现一个很高的方条,eg.1*1000000成为新的ans)。
HIT
- devcpp一生黑。如果一定要用devcpp,最好使用观察输出,不要用调试功能。
- 记得%d读不了负的long long,使用%lld代替。
代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long store[100009];//存数
long long stack[100009];//单调栈
long long width[100009];//存放宽度
int main()
{
int n;
while (scanf("%d", &n))
{
if (n == 0)break;
memset(width, 0, sizeof(width));
long long ans = 0;//最终答案
for (int i = 0; i < n; i++)
scanf("%lld", &store[i]);//记得%d读不了负的ll
int bottom = 0;
int top = 0;
stack[0] = store[0];
width[0] = 1;
for (int i = 1; i < n; i++)
{
if (store[i] >= stack[top])
{//满足递减栈
stack[++top] = store[i];
width[top] = 1;
continue;
}
else
{//找到一个比当前栈顶小的数 (小于等于)
long long num = 0;
while (top >= 0 && stack[top] >= store[i])
{
num += width[top];
long long temp = num * stack[top];
if (ans < temp) ans = temp;
top--;
}
stack[++top] = store[i];
width[top] = num + 1;
}
}
long long num = 0;
for (; top >= 0; top--)
{//剩余栈中元素计算有没有可能替代ans
num += width[top];
long long temp = num * stack[top];
if (ans < temp) ans = temp;
}
printf("%lld\n", ans);
}
return 0;
}