Corte de bambú (Competencia provincial Copa Lanqiao 2022, Grupo B, Pregunta J)

cortar bambú

Código CA:

#include<iostream>
#include<queue>
#include<math.h>
using namespace std;
long long res;
struct node
{
	long long val,l, r;
};

bool operator <(node a, node b)
{
	return a.val == b.val ? a.l < b.l : a.val < b.val;//定义调堆的规则,如果值相等的情况下,优先考虑左区间大的
}

int main(void)
{
	long long n, k;
	priority_queue<node>p;//定义一个node类型的堆
	scanf("%lld", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%lld", &k);
		p.push({ k,i,i });
	}
	while (p.top().val != 1)
	{
		node t = p.top();//取出当前的堆顶元素(最大值)
		p.pop();//先将最大值出堆,等砍掉之后还会将高度重新入堆
		node top;//用于等会记录堆中第二大的值
		while (!p.empty())
		{
			top = p.top();//堆中第二大的值
			if (t.val == top.val && t.l - 1 == top.r)//如果最大值和第二大的值相等,并且区间差只有1,就是相邻的竹子
			{
				p.pop();//一起砍掉,就是先pop掉第二大的,所有相等的且相邻的只用保留一个数就行了,当这个数被砍为1的时候相当于所有相邻的都被砍为1了
				t.l = top.l;//相当于合并区间了
			}
			else
			{
				break;//如果没有可以一并砍掉的就直接跳出循环
			}
		}
		int val = sqrtl(t.val / 2 + 1);//计算
		p.push({ val,t.l,t.r });//将砍了之后的高度加入堆中
		res++;//砍的次数+1
	}
	printf("%lld", res);
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/AkieMo/article/details/130002700
Recomendado
Clasificación