列表

详情


NC200606. B-麻烦的杰西

描述

    圣诞节那一天,杰西收到一个圣诞蛋糕,不过这个蛋糕有点参差不齐,具体地说这个蛋糕是由n个小蛋糕拼起来的,每个小蛋糕长度为1,宽度为1,高度为hi。这对于“精致”的杰西来说是不能容忍的,所以她决定来“横切”蛋糕。具体地说:圣诞蛋糕放在水平面上,杰西先沿某一高度水平横切过去,再留下相同高度并连续的小蛋糕们。也就是她会把不同高度的小蛋糕和虽然同一高度但与被留下的小蛋糕们不连续的小蛋糕扔掉。杰西不想浪费太多蛋糕,所以她想尽可能多地留下小蛋糕。

    请问杰西最多能留下多少体积的蛋糕和对应的蛋糕高度是多少?若横切后(当然也可以不横切),出现多个体积相同的蛋糕,杰西不需要得到高度最高的蛋糕,而是直接留下更靠左的蛋糕。

输入描述

多测试用例,用例数不超过10组

每个测试用例,第一行为一个正整数n(n<=100000)

第二行有n个整数hi代表每个小蛋糕的高度(1<=hi<=1000000000 )

输出描述

输出占一行。俩个整数H和C用空格隔开,分别代表被杰西留下的最多的小蛋糕的高度和总体积。

示例1

输入:

8
2 1 7 7 8 1 5 7

输出:

7 21

说明:

如图很明显选择橙色部分的蛋糕是杰西所能留下高度为7的最大体积的蛋糕了:7*(1+1+1)*1=21。
所以杰西会在高度为7的水平面切一刀,留下橙色部分的蛋糕,其他蛋糕均扔掉。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 80ms, 内存消耗: 1612K, 提交时间: 2019-12-29 14:56:57

#include <iostream>
#include <stack>
#include <algorithm>
using namespace std;

int main()
{
  int i, n, tmp;
  long long h[200000], ans, ansh, ret;
  stack<int> s;
  while (scanf("%d", &n) != EOF) {
    for (int i = 0; i < n; i++) scanf("%lld", &h[i]);
    ans = 0;
    i = 0;
    while (1) {
      if (i < n && (s.empty() || h[s.top()] <= h[i])) s.push(i++);
      else {
	tmp = s.top(); s.pop();
        ret = h[tmp] * (s.empty() ? i : (i - s.top() - 1));
        if (ret > ans) {
          ans =	ret;
          ansh = h[tmp];
        }
      }
      if (i >= n && s.empty()) break;
    }
    printf("%lld %lld\n", ansh, ans);
  }
  return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 61ms, 内存消耗: 4660K, 提交时间: 2020-07-17 16:02:31

#include<bits/stdc++.h>
using namespace std;

int t,h[100005],S[100005];
int main()
{
	long long i,j,n,ans1,ans2;
	while(~scanf("%lld",&n))
	{
		for(i=0;i<n;i++)scanf("%d",&h[i]);
		ans1=ans2=t=0,S[0]=-1;
		for(i=0;i<n;i++)
		{
			if(!t||(t&&h[i]>=h[S[t]]))S[++t]=i;
			else
			{
				while(t&&h[i]<h[S[t]])
				{
					j=S[t--];
					if(ans2<(i-S[t]-1)*h[j])ans2=(i-S[t]-1)*h[j],ans1=h[j];
				}
				S[++t]=i;
			}
		}
		while(t)
		{
			j=S[t--];
			if(ans2<(i-S[t]-1)*h[j])ans2=(i-S[t]-1)*h[j],ans1=h[j];
		}
		printf("%lld %lld\n",ans1,ans2);
	}
}

上一题