[ABC379D] Home Garden 题解

题目大意

给您 Q Q Q 个查询,请按顺序处理。

有以下三种类型:

  1. 1:准备一个空花盆,在里面放一株植物。这里,植物的高度是 0 0 0
  2. 2 T:等待 T T T 天。在此期间,现有植物的高度会增加 T T T
  3. 3 H:收获所有高度至少达到 H H H 的植株,并输出收获植株的数量。收获的植物会从花盆中移出。

假设执行第一类和第三类查询所需的时间为零。

题目分析

根据数据范围分析可以得出暴力的时间复杂度是 O ( n 2 ) O(n^2) O(n2) ,显然会超时。

其中有一个难题是如何给数组中每一个数都加上 T T T 呢?我们知道一个定理:给一个不等式两边同时加上或减去同一个数不等式依然成立。那么我们就可以把每一个数都加上 T T T 的操作等价于把之后每个查询的 H H H 变成 H H H- T T T 即可。

但是还有一个问题,如何判断是否高度至少达到 H H H 呢?我们可以先建立一个变量 S S S 来记录当前过去的天数。再把这个当前的 S S S 作为新建盆栽对应数组的值。然后查询数组的每个值是否小于 S − H S-H SH 即可。

还可不可以再优化呢?我们可以联想一下[NOIP2016 普及组] 海港
这道题目的解法,建一个队列,只要对以后没有用的数据就直接弹出即可。

#include<bits/stdc++.h>
//记得开long long 
#define int long long
using namespace std;
queue<int> q;
int t,s;
main(){
	cin>>t;
	while(t--){
		int op,t,h;
		cin>>op;
		if(op==1){
			//当前的s作为新建盆栽对应的值
			q.push(s);	
		}
		if(op==2){
			cin>>t;
			//把s加上过去的天数 
			s+=t;
		}
		if(op==3){
			int js=0;
			cin>>h;
			//不断弹出不符合的数据 
			while(q.empty()==0&&q.front()<=s-h){
				js++;
				q.pop();
			}
			cout<<js<<endl;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值