UVA1619 感觉不错 Feel Good

知识点:单调栈

这个题的难度还是给高了一点,其实就是绿题,一开始,看到这个题我想着用尺取法加单调队列来解决,用单调队列来维护尺取区间的最小值,但是我发现这个题给的条件很少,尺取法需要一定的条件来满足单调性使得遍历区间可以在线性时间内完成,然后我再看看就发现这个不就是单调栈的题目吗,完全和求最大子矩阵面积一模一样,每一个数,都是一个正方形,然后看看这些正方形排一起,最大子矩阵的面积是多少,这个式子就是这个含义,然后用单调栈做就行了,

这个题的坑点还是比较多的,首先是多组数据,其次是这个没有SPJ,面积最大的时候,我们要输出下边个数最少的,如果还一样,那么输入左下标最小的,但是这个我是从左向右遍历的,所以一直满足这个要求,就不用考虑,然后就是我用了前缀和这个题,一开始没有开long long,也是错了好几次,最后一个问题就是这个题的数据会有一个全零的,如果按照我一开始的写法,那么无法找到最短的区间,一个办法就是初始化答案数据为第一个元素的值,区间就是1,1,这样就把那种特殊情况包含进去了

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;

long long a[N], b[N];

int main() {
	int n;
	int T = 0;
	while (cin >> n) {
		if (T++) cout << endl;
		for (int i = 1; i <= n; i++) {
			cin >> a[i];
			b[i] = b[i - 1] + a[i];
		}
		int L[N], R[N];
		fill(L + 1, L + n + 1, 0);
		fill(R + 1, R + n + 1, n + 1);
		stack<int> s1;
		for (int i = 1; i <= n; i++) {
			while (!s1.empty() && a[i] < a[s1.top()]) {
				R[s1.top()] = i;
				s1.pop();
			}
			s1.push(i);
		}
		stack<int> s2;
		for (int i = n; i >= 1; i--) {
			while (!s2.empty() && a[i] < a[s2.top()]) {
				L[s2.top()] = i;
				s2.pop();
			}
			s2.push(i);
		}
		long long ans = a[1];
		int x = 1, y = 1;
		for (int i = 1; i <= n; i++) {
			long long tmp = a[i] * (b[R[i] - 1] - b[L[i]]);
			if (tmp > ans) {
				ans = tmp;
				x = L[i] + 1;
				y = R[i] - 1;
			} else if (tmp == ans && R[i] - L[i] - 2 < y - x) {
				x = L[i] + 1;
				y = R[i] - 1;
			}
		}
		cout << ans << endl << x << " " << y << endl;
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值