01、什么是杂题?
- 不需要算法的题目
- 考核思维、逻辑、编码能力(脑筋急转弯)
- 这种题有“模拟题、构造题、思维题、找规律题”,统称“杂题”
- 每次蓝桥杯都会出现,而且可能有好几题,是重要的得分点
- 可能比较简单,也可能比较难
02、例题解析
例题一 :修建灌木
修剪灌木2022年第十三届省赛,lanqiao0J题号2107(难度值★)
【问题描述】
爱丽丝要完成一项修剪灌木的工作。有N棵灌木整齐的从左到右排成一排。爱丽丝在每天傍晚会修剪一棵灌木,让灌木的高度变为0厘米。爱丽丝修剪灌木的顺序是从最左侧的灌木开始,每天向右修剪一棵灌木。当修剪了最右侧的灌木后,她会调转方向,下一天开始向左修剪灌木。直到修剪了最左的灌木后再次调转方向。然后如此循环往复。灌木每天从早上到傍晚会长高1厘米,而其余时间不会长高。在第一天的早晨,所有灌木的高度都是0厘米。爱丽丝想知道每棵灌木最高长到多高?
【输入格式】一个正整数N,含义如题面所述。
【输出格式】输出N行,每行一个整数,第行表示从左到右第i棵树最高能长到多高。【评测用例规模与约定】对于30%的数据,N≤10;对于100%的数据,1<N≤10000。
【例题解析】
- 由于每棵灌木都会在2N天内被剪为0,所以不会无限长高。
- 其中在第i棵时,它左边有i-1棵,右边有n-i棵。爱丽丝分别从左右绕回来,各需要2(i-1)和2(n-i)天,比较这两个时间大小,时间大的就是最大高度。(每天长 1 cm)
【代码演示】
n = int(input())
for i in range (1,n+1):
print (max (i-1, n-i)*2)
例题二:付账问题
付账问题2018年第九届蓝桥杯省赛,lanqiao0J题号174(难度值★★)
【题目描述】
· 有n个人出去吃饭,他们总共消费了S元。其中第i个人带了ai元。所有人带的钱的总数是足够付账的。现在问题来了:每个人分别要出多少钱呢?
为了公平起见,我们希望在总付钱量恰好为S的前提下,最后每个人付的钱的标准差最小。
我们约定,每个人支付的钱数可以是任意非负实数,即可以不是1分钱的整数倍。你需要输出最小的标准差是多少。
【输入描述】
第一行包含两个整数 n、S;
第二行包含 n 个非负整数
。
其中,
。
【输出描述】
输出最小的标准差,四舍五入保留 4 位小数。
保证正确答案在加上或减去
后不会导致四舍五入的结果发生变化。
【样例输入】
10 30
214 7 4 8 3 6 4 7【样例输出】
0.7928
【例题解析】
如果每人带的钱够多,人均完全一样,bi = S/n = avg,那就简单了,得X = 0。不过总有人钱不够,分两种情况讨论:
- 第i人带的钱不够平均数avg,他只能出他带的全部钱ai。
- 第i人带的钱比平均数avg多,他可以多摊一些。
【求解步骤】
- 对ai从小到大排序;
- 前一部分人的钱不够,那么就出他们所有的钱;
- 从总付钱数中扣除前一部分人出的钱,得剩余钱数为S’,以及后一部分人的出钱平均数avg’。
- 后一部分人的钱多,他们多出一些。怎么出?这部分人也分两类:
(i)、 比较有钱的,但是他的钱也不够avg’,那么他的钱还是要全出;
(ii)、非常有钱的,不管怎么摊他都有富余。
【代码演示】
from math import *
n, s = map(int,input( ).split( ))
a = list(map(int,input( ).split()))
a.sort() # 从大到小排序
avg = s/n
sum = 0
for i in range(n):
if a[i]*(n-i) < s: # 钱少的人
sum +=pow( a[i]-avg,2)
s -= a[i] # 剩余的钱
else: # 钱多的人
cur_avg = s/(n-i) #更新平均出钱数
sum +=pow(cur_avg-avg,2)*(n-i)
break
print("{:.4f}".format(sqrt(sum / n))) # 标准差(保留四位小数)
例题三:最少砝码
最少砝码2021年第十二届蓝桥杯省赛,lanqiao0J题号1461 (难度值★★★)
【问题描述】
你有一架天平。现在你要设计一套砝码,使得利用这些砝码可以称出任意小于等于N的正整数重量。那么这套砝码最少需要包含多少个砝码?注意砝码可以放在天平两边。
【输入格式】输入一行包含一个正整数N,1≤N≤ 10°。
【输出格式】输出一行表示答案。【样例输入】
7
【样例输出】
3
样例说明
3个砝码重量是 1、4、6,可以称出 1 至 7的所有重量。
1 = 1;
2 = 6 − 4(天平一边放 6,另一边放 4);
3 = 4 − 1;
4 = 4;
5 = 6 − 1;
6 = 6;
7 = 1 + 6;
少于 3 个砝码不可能称出 1 至 7 的所有重量。
评测用例规模与约定
对于所有评测用例,1 ≤ N ≤ 10000000001≤N≤1000000000。
【例题分析】
这是一道找规律题
- 题目要求给出最少数量的几个整数(砝码),通过加减组合得到1 ~N的整数。熟悉二进制的都知道,用1、2、4、8、16、...这些2的倍数,可以组合后相加得到任意整数。
- 不过,本题的砝码不仅可以相加,还可以放在天平的两边通过减法得到新的称重。
例如N = 3时,砝码可以是{1,2},也可以是{1,3}、{2,3}。
【方法】
- 设当前砝码称重范围是1~R。
- 加一个砝码w,并且要求不重复加w前已经能得到的称重,那么w将是一个很大的砝码。
- 新的称重范围是:{1,2,.. .,R, w-R, w-R+1,.. ., w, w+1, w+2,..., w+R}
- 因为从R到w-R需要是连续的,所以有w-R= R+1,即w = 2R+1。
- 也就是说,如果当前称重范围是1~R,那么加一个w = 2R+1的砝码,可以扩展到新的称重范围R’= w+R = 3R+1。
下面列表计算,每一行的“原砝码,原称重范围”是上一行的“新砝码,新称重范围”
这个表格给出了一种最少砝码的实现方式,这种实现方式最大程度扩展了新的R’,是一种最优方案。根据这个表格可以得到计算方法:
(1)砝码按3的倍数增长
(2)每加一个砝码,称重范围增长到R’= 3R+1。
N= int( input())# 目标质量
R= 1 # 初始化砝码质量
cnt = 1
while R<N: # 称重范围没有达到目标质量。这里R<N没有=,是因为=就不需要后面cnt再加一。
R =R*3 +1 # 范围扩展:3倍+1
cnt += 1 # 加一个砝码
print(cnt)