C语言蓝桥杯刷题:修剪灌木
题目链接
解题思路:
本题需要注意的是树是白天长,然后爱丽丝傍晩对某棵树进行修剪,也就是说树高度是可能在白天达到最大值而在傍晩变成0。我一开始也有一个误区,以为是要修剪的那棵树当天就变成0而不能生长,其实是先生长再修剪。
另外一个需要考虑的就是树的高度啥时候变最大呢?
不难理解,肯定是爱丽丝剪完这棵树,再长到她下次继续来修剪之前啦,可能有同学会问:如果是最后一棵树也是这样吗?答案是是的,它在第一次被修剪前是经过爱丽丝走一趟嘛,但是如果被修剪完再到下次被修剪前,爱丽丝要走两趟(向右再向左,加上第一次到该数,一共3趟)。
最后一个难点就是如何保证每棵树都是被修剪了2次
其实也很好想,采用极端思维,考虑第一棵树和最后一棵树,中间的情况都是在这两棵树之间的。
第一棵树:爱丽丝向右一趟,再向左一趟
第二棵树:爱丽丝向右一趟,再向左一趟,再向右一趟
所以三次循环就可以保证所有数都被剪了两次
而这三次循环中我们就可以统计出所有的树高最大值了
#include <stdio.h>
#include <stdlib.h>
void grow(int arr[], int n)//白天到傍晩所有树长了1cm
{
for (int i = 0;i < n;i++)
{
arr[i]++;
}
}
void cut(int arr[], int i)//爱丽丝傍晩对第i棵树进行修剪
{
arr[i] = 0;
}
void Max(int arr[], int crr[], int n)
{
for (int i = 0;i < n;i++)
{
if (arr[i] > crr[i])
{
crr[i] = arr[i];
}
}
}
int main(int argc, char *argv[])
{
// 请在此输入您的代码
int n = 0;
scanf("%d", &n);
int i = 0;//标记爱丽丝当前位置
int arr[3] = { 0 };//n棵树,arr[i-1]表示第i棵树当前高度
int crr[3] = { 0 };//crr[i-1]表示第i棵树的最大高度
//一棵树长最高也就是当天被修剪之后开始长到下次被修剪之前
//所以最多循环3次即可(第一次向右,第二次向左,第三次再向右)
//第一个树2次循环就可以长最高
//最后一棵树需要爱丽丝剪完向左再向右(加上第一次到该树一共3次)
for (i = 0;i < n;i++)
{
grow(arr, n);//白天到傍晩所有树长了1cm
Max(arr, crr, n);//当前所有树最高多少cm
cut(arr, i);//爱丽丝傍晩对第i棵树进行修剪
}
for (i = n - 2;i >= 0;i--)
{
grow(arr, n);//白天到傍晩所有树长了1cm
Max(arr, crr, n);//当前所有树最高多少cm
cut(arr, i);//爱丽丝傍晩对第i棵树进行修剪
}
for (i = 1;i < n;i++)
{
grow(arr, n);//白天到傍晩所有树长了1cm
Max(arr, crr, n);//当前所有树最高多少cm
cut(arr, i);//爱丽丝傍晩对第i棵树进行修剪
}
for (i = 0;i < n;i++)
{
printf("%d\n", crr[i]);
}
return 0;
}