[蓝桥杯 2022 省 B] 砍竹子(贪心)

题目描述

这天,小明在砍竹子,他面前有 n n n 棵竹子排成一排,一开始第 i i i 棵竹子的高度为 h i h_{i} hi.

他觉得一棵一棵砍太慢了,决定使用魔法来砍竹子。魔法可以对连续的一段相同高度的竹子使用,假设这一段竹子的高度为 H H H,那么使用一次魔法可以把这一段竹子的高度都变为 ⌊ ⌊ H 2 ⌋ + 1 ⌋ \left\lfloor\sqrt{\left\lfloor\frac{H}{2}\right\rfloor+1}\right\rfloor 2H+1 , 其中 ⌊ x ⌋ \lfloor x\rfloor x 表示对 x x x 向下取整。小明想知道他最少使用多少次魔法可以让所有的竹子的高度都变为 1 1 1

输入格式

第一行为一个正整数 n n n,表示竹子的棵数。

第二行共 n n n 个空格分开的正整数 h i h_{i} hi,表示每棵竹子的高度。

输出格式

一个整数表示答案。

样例 #1

样例输入 #1

6
2 1 4 2 6 7

样例输出 #1

5

提示

【样例说明】

其中一种方案:

214267 → 214262 → 214222 → 211222 → 111222 → 111111 214267\rightarrow 214262\rightarrow 214222\rightarrow 211222\rightarrow 111222\rightarrow 111111 214267214262214222211222111222111111

共需要 5 步完成

【评测用例规模与约定】

对于 20 % 20 \% 20% 的数据,保证 n ≤ 1000 , h i ≤ 1 0 6 n \leq 1000, h_{i} \leq 10^{6} n1000,hi106

对于 100 % 100 \% 100% 的数据,保证 n ≤ 2 × 1 0 5 , h i ≤ 1 0 18 n \leq 2 \times 10^{5}, h_{i} \leq 10^{18} n2×105,hi1018

蓝桥杯 2022 省赛 B 组 J 题。

解析

显然根据贪心,需要先砍高的竹子以便于凑“魔法”,所以遍历计算出每棵竹子应该砍伐的次数,然后不断砍次数最高的竹子

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N=2e5+5;
int n;
int a[N],cnt[N];
int check(int x){
	return (int)sqrt(x/2+1);
}
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		int x=a[i];
		while(x!=1){
			cnt[i]++;
			x=check(x);
		}
	}
	int ans=0,maxx=*max_element(cnt+1,cnt+n+1);
	for(int i=maxx;i>0;i--){
		for(int j=1;j<=n;j++){
			if(cnt[j]==i){
				if(a[j]!=a[j+1]) ans++;
				cnt[j]--;
				a[j]=check(a[j]);
			}
		}
	}
	cout<<ans;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int t=1;
//	cin>>t;
	while(t--) solve();
	return 0;
}
  • 21
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值