【每日一题】——修建灌木(蓝桥杯真题)

文章介绍了一个关于算法的问题,爱丽丝按照特定规则修剪灌木,每天灌木会长高。题目要求计算每棵灌木的最大高度。解决方案涉及数组处理和数学逻辑,代码展示了如何计算并输出每棵树的最大高度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.题目

题目描述:

爱丽丝要完成一项修剪灌木的工作。有 N 棵灌木整齐的从左到右排成一排。爱丽丝在每天傍晚会修剪一棵灌木,让灌木的高度变为 0 厘米。爱丽丝修剪灌木的顺序是从最左侧的灌木开始,每天向右修剪一棵灌木。当修剪了最右侧的灌木后,她会调转方向,下一天开始向左修剪灌木。直到修剪了最左的灌木后再次调转方向。然后如此循环往复。灌木每天从早上到傍晚会长高 1 厘米,而其余时间不会长高。在第一天的早晨,所有灌木的高度都是 0 厘米。爱丽丝想知道每棵灌木最高长到多高。

输入格式:

一个正整数 N ,含义如题面所述。

输出格式:

输出 N 行,每行一个整数,第i行表示从左到右第 i 棵树最高能长到多高。

样例输入:

3

样例输出:

4
2
4

二.分析

在这里插入图片描述

这题画图之后思路会非常清晰,可以看成0的移动(0从该位置移动后回到该位置的最大的次数),我图片中框出来的数字是剪掉之后的最大高度,真实的最大高度应该是修剪前的高度,所以应该加1,并且左右对称的灌木最大高度是相同的

三.代码展示

#include<stdio.h>
int main()
{
	long long arr[1000] = { 0 };
	long long N = 0;//N棵树
	long long i = 0;//循环变量
	scanf("%lld", &N);
	int k = 0;
	if (N % 2 == 0)
	{
		k = N / 2;//画图后可以得知左右两边树的最大高度是对称的
	}
	else if (N % 2 == 1)
	{
		k = N / 2 + 1;
	}
	for (i = 0; i <k ; i++)
	{
		arr[i] = (N - i - 1) * 2 ;
		arr[N-i-1]= (N - i - 1) * 2 ;
	}
	for (i = 0; i < N; i++)
	{
		printf("%lld\n", arr[i]);
	}
	return 0;
}

最后:

每日一题系列旨在养成刷题的习惯,所以对代码的解释并不会特别详细,但足够引导大家写出来,选的题目都不会特别难,但也不是特别简单,比较考验大家的基础和应用能力,我希望能够将这个系列一直写下去,也希望大家能够和我一起坚持每天写代码。

在这里送大家一句话:广积粮,缓称王!

### 关于蓝桥杯 C++ 题目的解题思路与示例代码 #### D. 修剪灌木 此问题的核心在于通过模拟的方式解决。给定三个变量 `a`、`b` 和 `n`,分别表示两种类型的灌木数量以及总长度限制。程序的目标是计算最多可以种植多少株灌木。 以下是完整的逻辑解析和实现: - **核心算法**: 使用贪心策略来最大化灌木的数量。每次尝试尽可能多地放置灌木,并更新剩余空间。 - **具体步骤**: - 初始化每种灌木的成本数组 `[a, a, a, a, a, b, b]` 表示前五个位置成本为 `a`,最后两个位置成本为 `b`。 - 不断减少剩余的空间并增加计数器直到无法再放置更多灌木为止。 ```cpp #include <bits/stdc++.h> using namespace std; int main() { long long a, b, n; cin >> a >> b >> n; long long sum = 5 * a + 2 * b; // 每轮循环所需的最大开销 long long ans = n / sum * 7; // 初始最大可能的灌木总数 long long res = n % sum; // 剩余可用空间 long long date[7] = {a, a, a, a, a, b, b}; for (int i = 0; res > 0; i++) { res -= date[i % 7]; if (res >= 0) ans++; } cout << ans << endl; return 0; } ``` --- #### 翻硬币问题 对于翻转硬币的问题,其主要目标是比较两字符串的不同之处并通过最小化操作次数完成匹配。 - **核心算法**: 找到所有不同的字符索引,并统计这些不同索引间的距离作为翻转次数。 ```cpp #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; int main() { int len, j = 0, sum = 0; char s1[10], s2[10]; int a[10] = {0}; scanf("%s", s1); scanf("%s", s2); len = strlen(s1); for (int i = 0; i < len; i++) { if (s1[i] != s2[i]) { // 当两个串出现不相等时记录该点的位置 a[j++] = i; } } for (int i = 0; i < j; i += 2) { // 两个两个地翻转硬币 sum += a[i + 1] - a[i]; } printf("%d\n", sum); return 0; } ``` --- #### 浮点数转换问题 本问题是基于简单的数学运算,涉及指数增长和四舍五入的操作。 - **核心算法**: 给定浮点数 `d` 和整数 `n`,先将其乘以 \(2^n\) 并进行四舍五入得到最终结果。 ```cpp #include <iostream> // 用于输入输出操作 #include <cmath> // 提供pow()和round()数学函数 using namespace std; int main() { int n; // 转换参数n,必须是整数 double d; // 待转换的浮点数d,题目保证d > 0 cin >> n >> d; // 输入处理:按顺序读取整数n和浮点数d double m = d * pow(2, n); // 计算 d * 2^n long long ans = round(m); // 四舍五入到最近的整数 cout << ans << endl; // 输出最终结果 return 0; } ``` --- #### 小球反弹路径问题 这是一个几何学中的经典物理运动轨迹问题,涉及到速度分解和碰撞检测。 - **核心算法**: 根据初始条件计算小球在水平方向上的周期性移动时间,并利用勾股定理求得总的位移距离。 ```java package 十五届; import static java.lang.Math.sqrt; public class 小球反弹 { public static void main(String[] args) { int x = 343720; int y = 233333; int dx = 15; int dy = 17; int p = y * dx; int q = x * dy; int g = gcd(p, q); p /= g; q /= g; int t = 2 * p * x / dx; double ans = t * sqrt(dx * dx + dy * dy); System.out.printf("%.2f", ans); // 结果保留两位小数 } public static int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } } ``` ---
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PH_modest

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值