蓝桥杯倒计时 | 倒计时20天

作者🕵️‍♂️:让机器理解语言か

专栏🎇蓝桥杯倒计时冲刺

描述🎨:蓝桥杯冲刺阶段,一定要沉住气,一步一个脚印,胜利就在前方!

寄语💓:🐾没有白走的路,每一步都算数!🐾

目录

 题目1:信号覆盖 

思路: 

代码: 

题目2:滑行 

思路: 

代码:

题目三:购物单 

解决方法一:Excel 

解决方法二:代码


 题目1:信号覆盖 

信号覆盖 - 蓝桥云课 (lanqiao.cn)

问题描述

小蓝负责一块区域的信号塔安装,整块区域是一个长方形区域,建立坐标轴后,西南角坐标为 (0,0), 东南角坐标为 (W,0), 西北角坐标为 (0,H), 东北角坐标为 (W,H)。其中 W, H 都是整数。他在 n 个位置设置了信号塔,每个信号塔可以覆盖以自己为圆心,半径为 R 的圆形(包括边缘)。为了对信号覆盖的情况进行检查,小蓝打算在区域内的所有横纵坐标为整数的点进行测试,检查信号状态。其中横坐标范围为 0 到 W,纵坐标范围为 0 到 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 _ in range(n):
    x,y = map(int,input().split())
    x1, x2 = max(x-r,0), min(x+r,w)  # 遍历左右坐标
    y1, y2 = max(y-r,0), min(y+r,h)  # 遍历上下坐标
    for i in range(x1,x2+1): # 将坐标对应的区域遍历
        for j in range(y1,y2+1):
            if abs(i-x)*abs(i-x) + abs(j-y)*abs(j-y) <= r*r: # 判断点到圆点的距离
                l.add((i,j)) # 满足就添加到集合里面自动去重了
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 = 1
    for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]: # 当前位置的四个方向
        xx = dx + x
        yy = dy + y
        if 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)达到最远的距离 + 1
    jiyi[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.5
        else:
            discount = float(discount[:-1])*0.1 
    else:                       # 折扣是三个字符的
        discount = float(discount[:-1])*0.01
    sum += price*discount       # 购物总金额
print(math.ceil(sum/100)*100)     # math.ceil向上取整    

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小叶pyか

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

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

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

打赏作者

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

抵扣说明:

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

余额充值