作者🕵️♂️:让机器理解语言か
专栏🎇:蓝桥杯倒计时冲刺
描述🎨:蓝桥杯冲刺阶段,一定要沉住气,一步一个脚印,胜利就在前方!
寄语💓:🐾没有白走的路,每一步都算数!🐾
目录
题目1:信号覆盖
思路:
代码:
题目2:滑行
思路:
代码:
题目三:购物单
解决方法一:Excel
解决方法二:代码
题目1:信号覆盖
信号覆盖 - 蓝桥云课 (lanqiao.cn)
问题描述
小蓝负责一块区域的信号塔安装,整块区域是一个长方形区域,建立坐标轴后,西南角坐标为 (0,0), 东南角坐标为 (W,0), 西北角坐标为 (0,H), 东北角坐标为 (W,H)。其中 W, H 都是整数。他在 n 个位置设置了信号塔,每个信号塔可以覆盖以自己为圆心,半径为 R 的圆形(包括边缘)。为了对信号覆盖的情况进行检查,小蓝打算在区域内的所有横纵坐标为整数的点进行测试,检查信号状态。其中横坐标范围为 0 到 W,纵坐标范围为 00 到 H,总共测试(W+1)×(H+1) 个点。
给定信号塔的位置,请问这 (W+1)×(H+1) 个点中有多少个点被信号覆盖。
输入格式
输入第一行包含四个整数 W,H,n,R,相邻整数之间使用一个空格分隔。
接下来 n 行,每行包含两个整数 x,y,表示一个信号塔的坐标。信号塔可能重合,表示两个信号发射器装在了同一个位置。
输出格式
输出一行包含一个整数,表示答案。
样例输入
10 10 2 5 0 0 7 0
样例输出
57
评测用例规模与约定
对于所有评测用例,1≤W,H≤100,1≤n≤100,1≤R≤100,0≤x≤W,0≤y≤H。
思路:
1、怎么确定一点在区域的范围内?
为了减小遍历区间范围,所以首先确定该信号塔范围的边界,只在信号塔所在圆的外切正方形内搜索:
左右边界: x1, x2 = x-r, x+r
上下边界: y1, y2 = y-r, y+r
再用两层循环遍历左右边界和上下边界,如果x<0或x>w,y<0或y>h说明该点不在范围内。
2、怎么统计信号塔范围内点的数量?
首先判断该点是否在圆内:abs(i1-x)*abs(i1-x) + abs(j1-y)*abs(j1-y) <= r*r(负数不能相乘,先用abs()取绝对值)
若在圆内则添加到集合l,对于两个信号塔范围重叠部分的坐标,集合会自动去重,最后取出集合l的长度就是信号塔范围内的点数
代码:
l = set(()) # 去掉重复的点
w,h,n,r = map(int,input().split())
for i in range(n):x,y = map(int,input().split())x1, x2 = x-r, x+r # 遍历左右坐标y1, y2 = y-r, y+r # 遍历上下坐标for i1 in range(x1,x2+1): # 将坐标对应的区域遍历if i1 <0 or i1 > w: # 判断超过区域的数直接跳过continuefor j1 in range(y1,y2+1):if j1 < 0 or j1 > h: #判断超过区域的数直接跳过continueif abs(i1-x)*abs(i1-x) + abs(j1-y)*abs(j1-y) <= r*r: # 判断点到圆点的距离l.add((i1,j1)) # 满足就添加到集合里面自动去重了
print(len(l))
题目2:滑行
滑行 - 蓝桥云课 (lanqiao.cn)
问题描述
小蓝准备在一个空旷的场地里面滑行,这个场地的高度不一,小蓝用一个 n 行 m 列的矩阵来表示场地,矩阵中的数值表示场地的高度。如果小蓝在某个位置,而他上、下、左、右中有一个位置的高度(严格)低于当前的高度,小蓝就可以滑过去,滑动距离为 1 。如果小蓝在某个位置,而他上、下、左、右中所有位置的高度都大于等于当前的高度,小蓝的滑行就结束了。小蓝不能滑出矩阵所表示的场地。小蓝可以任意选择一个位置开始滑行,请问小蓝最多能滑行多远距离。
输入格式
输入第一行包含两个整数 n, m,用一个空格分隔。
接下来 n 行,每行包含 m 个整数,相邻整数之间用一个空格分隔,依次表示每个位置的高度。
输出格式
输出一行包含一个整数,表示答案。
样例输入
4 5 1 4 6 3 1 11 8 7 3 1 9 4 5 2 1 1 3 2 2 1
样例输出
7
样例说明
滑行的位置一次为 (2,1),(2,2),(2,3),(3,3),(3,2),(4,2),(4,3)(2,1),(2,2),(2,3),(3,3),(3,2),(4,2),(4,3)。
评测用例规模与约定
对于 30% 评测用例,1 <= n <= 20,1 <= m <= 20,0 <= 高度 <= 100。
对于所有评测用例,1 <= n <= 100,1 <= m <= 100,0 <= 高度 <= 10000。
思路:
一道简单的搜索题,用深度优先搜索(DFS)来写
小蓝可以从任意一点出发,所以从地图上每一点 开始搜索,用两层循环遍历每一点。
DFS过程就是搜索当前位置所能达到的最远距离
- 记忆化:jiyi( )记录了当前位置所能达到的最远距离,后面再遇到就不再运算重复路线,直接返回当前位置所能达到的最远距离。
- 遍历当前位置的四个方向,求出下一点的坐标;如果下一点在界内且下一点比当前点更低,则取出四个方向的点中可以达到的最远距离。四个方向的点中可以达到的最远距离+1就是当前点可以到达的最远距离。用列表jiyi( )进行记录当前点可以到达的最远距离(记忆化)。
代码:
n, m = map(int, input().split())
lst = [list(map(int, input().split())) for _ in range(n)] # 二维列表保存地图高度
jiyi = [[-1] * m for _ in range(n)] # 记忆化搜索
# 记忆化搜索: -1代表没记录当前位置所能达到的最远距离,其他值代表已经记录了当前位置所能达到的最远距离def dfs(x, y): # 搜索当前位置所能达到的最远距离if jiyi[x][y] != -1: # 如果被记录过了return jiyi[x][y] # 直接返回当前位置所能达到的最远距离ans = 1for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]: # 当前位置的四个方向xx = dx + xyy = dy + yif 0 <= xx < n and 0 <= yy < m and lst[xx][yy] < lst[x][y]: # 在界内且下一个位置比当前位置低ans = max(dfs(xx, yy) + 1, ans) # dfs(xx, yy) + 1:(x, y)达到最远的距离=(xx, yy)达到最远的距离 + 1jiyi[x][y] = ans # 每次走到尽头了就记录一下当前这条路线走了几步(距离)return ans # 返回当前位置所能达到的最远距离res = 0
# 可以从任意一个点出发,所以遍历地图所有点
for i in range(n):for j in range(m):res = max(dfs(i, j), res) # 所有位置所能达到的最远距离print(res)
题目三:购物单
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。小明刚刚找到工作,老板人很好,只是老板夫人很爱购物。老板忙的时候经常让小明帮忙到商场代为购物。小明很厌烦,但又不好推辞。
这不,大促销又来了!老板夫人开出了长长的购物单,都是有打折优惠的。
小明也有个怪癖,不到万不得已,从不刷卡,直接现金搞定。
现在小明很心烦,请你帮他计算一下,需要从取款机上取多少现金,才能搞定这次购物。
取款机只能提供 100 元面额的纸币。小明想尽可能少取些现金,够用就行了。 你的任务是计算出,小明最少需要取多少现金。
以下是让人头疼的购物单,为了保护隐私,物品名称被隐藏了。
**** 180.90 88折 **** 10.25 65折 **** 56.14 9折 **** 104.65 9折 **** 100.30 88折 **** 297.15 半价 **** 26.75 65折 **** 130.62 半价 **** 240.28 58折 **** 270.62 8折 **** 115.87 88折 **** 247.34 95折 **** 73.21 9折 **** 101.00 半价 **** 79.54 半价 **** 278.44 7折 **** 199.26 半价 **** 12.97 9折 **** 166.30 78折 **** 125.50 58折 **** 84.98 9折 **** 113.35 68折 **** 166.57 半价 **** 42.56 9折 **** 81.90 95折 **** 131.78 8折 **** 255.89 78折 **** 109.17 9折 **** 146.69 68折 **** 139.33 65折 **** 141.16 78折 **** 154.74 8折 **** 59.42 8折 **** 85.44 68折 **** 293.70 88折 **** 261.79 65折 **** 11.30 88折 **** 268.27 58折 **** 128.29 88折 **** 251.03 8折 **** 208.39 75折 **** 128.88 75折 **** 62.06 9折 **** 225.87 75折 **** 12.89 75折 **** 34.28 75折 **** 62.16 58折 **** 129.12 半价 **** 218.37 半价 **** 289.69 8折
需要说明的是,88 折指的是按标价的 88计算,而 8 折是按 80 计算,余者类推。 特别地,半价是按 50 计算。
请输出小明要从取款机上提取的金额,单位是元。
解决方法一:Excel
【特别说明】 本文excel解法思路来自官网题库题解中关于EXCEL解法的高赞回答,因为对excel操作不熟练,实操比较坎坷,特此记录详细过程并分享。
具体步骤(图演示)
1.将数据复制进excel中,点数据中的分列,将文本分成3列。
1.1 复制题目中购物单文本 → 打开excel → 选择A1单元格 → 粘贴→选择性粘贴(文本和Unocode文本均可);
1.2 粘贴完毕→选择A1整列→菜单栏选择数据→选择分列→固定宽度→一直点"下一步"即可;
2.将折扣那一列文本中的“折”字替换成“空格”,半折替换成5
选择C列 → ctrl+h 打开替换(或者菜单栏开始→ 查找 → 替换 )→ 查找内容填写”折“,替换为空格(敲一下回车),查找内容填写半价时替换为5 →选择全部替换;
3.再在旁边一列中输入前两个想要的格式如0.88 0.65,选中下一格按ctrl+e 自动填充得到一列0.88 0.65 0.9等格式的数据。
注意:D列要至少输入两个数值,否则自动填充时的结果不完全为想要的格式。
4.最后就是基本的excel公式的运用指定格相乘 最后求和得到结果。
4.1 选择E1单元格 → 输入 =B1*D1 → 回车得到结果;
4.2 下拉E1单元格绿框右下角小绿点至最后一条数据,得到每一件商品打折后的价格;
4.3 最后在F1单元格输入 =SUM(E:E) ,得到E列所有数据求和结果值:5136.8595;因为题目要求只能取整百元,所以题目所求值结果应为5200。
所以购物的总金额为5136.86,但取款机只能提供 100 元面额的纸币,所以小明应该取出5200元,直接打印print(5200),成功AC!
解决方法二:代码
import math
data = '''
**** 180.90 88折
**** 10.25 65折
**** 56.14 9折
**** 104.65 9折
**** 100.30 88折
**** 297.15 半价
**** 26.75 65折
**** 130.62 半价
**** 240.28 58折
**** 270.62 8折
**** 115.87 88折
**** 247.34 95折
**** 73.21 9折
**** 101.00 半价
**** 79.54 半价
**** 278.44 7折
**** 199.26 半价
**** 12.97 9折
**** 166.30 78折
**** 125.50 58折
**** 84.98 9折
**** 113.35 68折
**** 166.57 半价
**** 42.56 9折
**** 81.90 95折
**** 131.78 8折
**** 255.89 78折
**** 109.17 9折
**** 146.69 68折
**** 139.33 65折
**** 141.16 78折
**** 154.74 8折
**** 59.42 8折
**** 85.44 68折
**** 293.70 88折
**** 261.79 65折
**** 11.30 88折
**** 268.27 58折
**** 128.29 88折
**** 251.03 8折
**** 208.39 75折
**** 128.88 75折
**** 62.06 9折
**** 225.87 75折
**** 12.89 75折
**** 34.28 75折
**** 62.16 58折
**** 129.12 半价
**** 218.37 半价
**** 289.69 8折
'''
data = data.split()
sum = 0
for i in range(0,len(data),3):price = float(data[i+1]) # 取出每个商品价格discount = data[i+2] # 取出每个商品折扣if len(discount) == 2: # 折扣是两个字符if discount == "半价":discount = 0.5else:discount = float(discount[:-1])*0.1 else: # 折扣是三个字符的discount = float(discount[:-1])*0.01sum += price*discount # 购物总金额
print(math.ceil(sum/100)*100) # math.ceil向上取整