[海豹海边爆]Daimayuan501

原题链接:拆方块 - 题目 - Daimayuan Online Judge

解题思路:首先我们假设,如果不考虑左右,并且所有方块都等高,那么他们消除需要多久呢?答案是等于高度,因为每一次都只会消去最上面一层。

那么肯定有人要问了,这题目里面每一根柱子也不等高啊?如果一个柱子本身很高,而旁边只有一格,那不是就错了吗?所以我们不难发现,一根柱子的完全消除,还取决于左右两侧柱子的消除时间。

同样不难发现,左右两侧必定在第一次操作就消失。我们可以先从左往右遍历一次,自己的左侧柱子消除时间与自己柱子高度取小值,再从右往左类似的遍历一次,在两次遍历形成的数组取小值即可。

那么又有人要问了,如果假设左右两侧柱子无限多且无限高,另有一根柱子高m,另一根高n,而且m远大于n的话,高度为m的柱子不也是n+1秒就消失了吗?没错,所以这个做法其实是考虑到这个问题的。我们假设那根高度为n的柱子在高度为m的柱子左边。因为是从左往右更新,所以高n的柱子在n次操作后才会消失,而m高的柱子虽然第一次操作时就变成了高度n,但哪怕只考虑m高柱子本身,也只需要n+1次操作就消失,与左侧消失后将其消除的值是完全一致的。而右侧重新往左更新一次,就能让右侧堆对左侧影响了。

最后,输出两个数组中每个值取较小值(就是每个堆从左往右遍历和从右往左遍历得到的两个值取小值)后的最大值。

AC代码:

#include<bits/stdc++.h>
using namespace std;
long long n,h[100010],r[100010],l[100010],maxx=0;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++) scanf("%lld",&h[i]);//输入 
	for(int i=1;i<=n;i++) l[i]=min(h[i],l[i-1]+1);//从左往右遍历,考虑左侧堆时间+1和自己高度的较小值为只考虑左堆影响时自己消失的时间 
	for(int i=n;i>=1;i--) r[i]=min(h[i],r[i+1]+1);//从右往左遍历,考虑右侧堆时间+1和自己高度的较小值为只考虑右堆影响时自己消失的时间 
	for(int i=1;i<=n;i++) maxx=max(maxx,min(l[i],r[i]));//两次遍历中的较小值就是这个堆实际消失的时间,这当中的最大值就是整个堆消失的时间 
	cout<<maxx;
	return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值