【小赛1】蓝桥杯双周赛第5场(小白)思路回顾

我的成绩:小白(5/6)

完稿时间:2024-2-13

比赛地址:https://www.lanqiao.cn/oj-contest/newbie-5/

相关资料:

1、出题人题解:“蓝桥杯双周赛·第5次强者挑战赛/小白入门赛”出题人题解 - 知乎 (zhihu.com)

2、矩阵快速幂:算法学习笔记(4):快速幂 - 知乎 (zhihu.com)

  • 讲得挺好的,从快速幂到矩阵快速幂,以及在求解递推式中的应用。

3、矩阵乘法结合律证明:如何把矩阵乘法结合律的证明写得简单易懂(针对初学者) - 知乎 (zhihu.com)

  • 我突然疑惑矩阵乘法为什么会满足结合律,找了篇文章,还没来得及看

文章目录

  • 一、我思路回顾
    • 1、十二生肖
    • 2、欢迎参加福建省大学生程序设计竞赛
    • 3、匹配二元组的数量
    • 4、元素交换
    • 5、下棋的贝贝
  • 二、补题
    • 6、方程
  • 三、小结
    • *脱节:从实践出发,又要从基础出发
    • 回顾此回顾

一、我思路回顾

1、十二生肖

思路:

此题令我有点意外,显然2024是龙年,在12生肖中排第5个,print即可。

代码:

print(5)

2、欢迎参加福建省大学生程序设计竞赛

思路:

题中说将相同题数,相同罚时的队伍归为一类,那么如果每行输入作为一个元素,问题就变成了:有多少个不同的元素。而刚好集合数据结构就具有元素不重复的特点,将所有输入数据加入集合,输出集合中元素数量即可。

在python中,输入是字符串,将它作为字典的键就可实现去重。

代码:

if __name__ == '__main__':n = int(input())d = {}for i in range(n):x = input()if x not in d:d[x] = 1print(len(d))

3、匹配二元组的数量

思路:

这题想了一会儿,看到比值就想一项,但移完之后呢?

a i j = a j i \frac{a_i}{j}=\frac{a_j}{i} jai=iaj,变形一下, i a i = j a j ia_i=ja_j iai=jaj,于是可以将数组A的每一元素乘以它的下标,得新数组B,后统计B中重复元素数量。(注这里下标从1开始)

出现2次的算1一个匹配二元组,出现3次的算3个······出现x次的算组合数 C x 2 C^2_x Cx2,即 x ! 2 \frac{x!}{2} 2x!

代码:

def f(x):'''x的阶乘'''r = 1for i in range(x):t = i + 1r *= t return rif __name__ == '__main__':n = int(input())nums = [int(x) for x in input().split(' ')]d = {}for i, num in enumerate(nums):nums[i] = (i + 1) * num for num in nums:if num not in d:d[num] = 0d[num] += 1result = 0for key in d:result += f(d[key]) // 2print(result)

4、元素交换

思路:

这题像脑筋急转弯,初看非常的手足无措。

数组中有N个0和N个1,“不存在连续的0或1”,那合规数组仅两种:1)010101...,2)101010...,于是逐项对比输入与合规数组,得不同的项的数量c,而每次交换可以把两个不同项变为相同,所以交换次数为n/2 。

那为什么,每次交换可以减少两个不同?

因为1对上0的数量,必然和0对上1的数量一样。不妨令N为5,假设合规数组中,有3个1没匹配上。那么必然有2个1匹配上了,那么输入中还剩3个1,让合规数组中的0也有3个匹配不上。

合规:0 1 0 1 0 1 0 1 0 1
输入:  0   0   0   1   1

在比赛中,我经常就只能先将输入胡乱摆弄一阵,然后去猜规律,有时猜得对,有时猜得半对,有时猜得不对。在下一题,下棋的贝贝中,就是先草率地猜错了,然后又重新猜。

代码:

def jdz(x):'''绝对值'''return x if x >= 0 else -xif __name__ == '__main__':n = int(input())nums = [int(x) for x in input().split(' ')]# 合规数组h1 = [0, 1] * n h2 = [1, 0] * n# 对比差距c1 = sum([jdz(h1[i] - nums[i]) for i in range(len(nums))])c2 = sum([jdz(h2[i] - nums[i]) for i in range(len(nums))])c = min(c1, c2)r = c // 2  # 每次交换可以减少两个不同print(r)

5、下棋的贝贝

思路:

题意还比较清晰,在整数格子上放棋子,横竖挨着的棋子算相邻,相邻的棋子有一条边,如果边的总数为e,输出 2 ∗ e 2*e 2e

于是我开始在草稿纸上施法,期待老天爷降下神谕。很快我就觉得,这是一个类似等差的数列,之后隔两项的差都是3。然而提交之后的error告诉我,还是高兴得太早了。

在这里插入图片描述

于是我又猜了第二版。有的棋子放下时不增加边(1号)或只会增加一条边,如下图中带圈圈的;有的棋子放下时增加两条边,如下图中不带圈圈的。然后统计带圈圈类型的棋子数量。

设总棋子数为m,平方根向下取整为n,于是带圈圈的棋子数single_edge分两类统计:

  1. 一个是内侧正方形中的(如图中蓝框),数量为2n-1
  2. 外正方形的,会有两个临界值,当m的值超过它们时,带圈圈的棋子数加1。

如果每个棋子会产生两条边,那么总边数为 2 m 2m 2m。然后减去只产生一条边的棋子数量(因为一号棋子不产生边,可以抵两个只产生一条边的棋子),就可以得到边的总数。

在这里插入图片描述

为什么以上方法就是放置棋子的最佳策略(产生最多的边)?

大家可以思考一下。

代码:

import mathdef method2(m):'''边的数量'''n = math.sqrt(m)n = math.floor(n)single_edge = n * 2if m >= n**2 + 1:single_edge += 1if m >= n**2 + 1 + n:single_edge += 1 r = 2 * m - single_edgereturn rif __name__ == '__main__':m = int(input())r = method2(m)print(r * 2)

二、补题

6、方程

这题当时完全没有思路,希望我下次会有进步。如果还没有,就多下几次!

思路:

有两个步骤。第一步是得到递推式,但n数据范围是 [ 1 , 1 0 9 ] [1,10^9] [1,109],逐步递推时间复杂度 O ( n ) O(n) O(n)太高。于是第二步用到矩阵快速幂,将复杂度降到 O ( l o g n ) O(logn) O(logn)

1、得到递推式

题为 x + 1 x = k x+\frac{1}{x}=k x+x1=k,求 x n + 1 x n x^n+\frac{1}{x^n} xn+xn1的值。令 f ( n ) = x n + 1 x n f(n)=x^n+\frac{1}{x^n} f(n)=xn+xn1,则: k f ( n ) = ( x + 1 x ) ( x n + 1 x n ) = f ( n + 1 ) + f ( n − 1 ) kf(n)=(x+\frac{1}{x})(x^n+\frac{1}{x^n})=f(n+1)+f(n-1) kf(n)=(x+x1)(xn+xn1)=f(n+1)+f(n1)

即: f ( n + 1 ) = k f ( n ) − f ( n − 1 ) f(n+1)=kf(n)-f(n-1) f(n+1)=kf(n)f(n1)

又易得: f ( 0 ) = 2 f(0)=2 f(0)=2 f ( 1 ) = k f(1)=k f(1)=k

2、矩阵快速幂

这部分参考了文首的资料1和资料2,大家也可以看一下。

a、为什么要有快速幂算法?

在求一个数的n次幂的过程中,比如 1 0 8 = 10 ∗ 10 ∗ 10 ∗ 10 ∗ 10 ∗ 10 ∗ 10 ∗ 10 10^8=10*10*10*10*10*10*10*10 108=1010101010101010,需要8次乘法运算。但如果这样算: 1 0 2 = 10 ∗ 10 , 1 0 4 = 1 0 2 ∗ 1 0 2 , 1 0 8 = 1 0 4 ∗ 1 0 4 10^2=10*10,10^4=10^2*10^2,10^8=10^4*10^4 102=1010104=102102108=104104,只需要3次乘法,这其实是二分的思路。

也就是说,可以以 O ( l o g n ) O(logn) O(logn)的时间复杂度计算数x的n次幂 x n x^n xn

b、矩阵乘法如何计算递推式?

就以本题为例,我们发现 [ k − 1 1 0 ] [ f n − 1 f n − 2 ] = [ f n f n − 1 ] \begin{bmatrix}k & -1 \\ 1 & 0 \end{bmatrix} \begin{bmatrix}f_{n-1}\\f_{n-2} \end{bmatrix} = \begin{bmatrix}f_{n}\\f_{n-1} \end{bmatrix} [k110][fn1fn2]=[fnfn1] ,于是我们每一次矩阵乘法,就是一步递推。

但这有什么用呢,好像莫名奇妙凑出一个矩阵的形式,把简单的问题复杂化。

c、快速幂加上矩阵乘法:快速计算递推式。

A = [ k − 1 1 0 ] A=\begin{bmatrix}k & -1 \\ 1 & 0 \end{bmatrix} A=[k110] ,则: [ f n f n − 1 ] = A [ f n − 1 f n − 2 ] = A 2 [ f n − 2 f n − 3 ] = . . . = A n − 1 [ f 1 f 0 ] \begin{bmatrix}f_{n}\\f_{n-1} \end{bmatrix} = A \begin{bmatrix}f_{n-1}\\f_{n-2} \end{bmatrix} = A^2 \begin{bmatrix}f_{n-2}\\f_{n-3} \end{bmatrix} = ... = A^{n-1} \begin{bmatrix}f_{1}\\f_{0} \end{bmatrix} [fnfn1]=A[fn1fn2]=A2[fn2fn3]=...=An1[f1f0]

看见 A A A头上的幂次了吗?将递推的时间复杂度从 O ( n ) O(n) O(n)降到 O ( l o g n ) O(logn) O(logn),我想你已经知道该怎么做了。

代码:

class Matrix:'''封装矩阵乘法'''MOD_NUM = 10**9 + 7def __init__(self, value) -> None:self.v: list = value def mul(self, obj):# 两个矩阵维度分别是(a,b), (b,c)obj: Matrix = obja, b, c = len(self.v), len(self.v[0]), len(obj.v[0])matrix = [[0] * c for i in range(a)]  # 乘积维度:(a,c)r = Matrix(matrix)for i in range(a):for j in range(c):for k in range(b):r.v[i][j] = (r.v[i][j] + self.v[i][k] * obj.v[k][j]) % self.MOD_NUMreturn rdef mi(A: Matrix, n: int) -> Matrix:'''求矩阵A的n次幂'''if n == 1:return Aif n % 2 == 1:return mi(A, n-1).mul(A)else:t = mi(A, n // 2)return t.mul(t)def method(n, k):'''求解一个测试用例'''if n == 1:return k elif n > 1:A = Matrix([[k, -1], [1, 0]])F = Matrix([[k], [2]])  # f(0)=2, f(1)=kR = mi(A, n-1).mul(F)return R.v[0][0]if __name__ == '__main__':m = int(input())for _ in range(m):n, k = map(int, input().split(' '))  # 以前我总用列表推导式print(method(n, k))

这次比赛强者级还有3个题,但比赛就没看,相关内容也没咋学,又考虑到时间问题,就不打算补了。

三、小结

本次比赛有小白和强者两个级别,感觉自己还比较菜,于是报了小白。后来发现小白的后3题正是强者级的头三题,这么看来,我在强者级只能写两个题?但问题不大,我对未来仍然抱有一种迷之信心。

*脱节:从实践出发,又要从基础出发

脱节问题在我们的生活中尤其严重。常有人说大学教育与社会需求脱节。然而细看我自己,又何尝不是处处脱节?就如学英语数十年,却不能说英语,学习和运用是脱节的。读英文时脑海里止步于模糊的“英式汉语”,想将心中的地道汉语用英语说出来,自然是困难的,因为缺少了一个从输入英语到地道汉语的过程。盲目期待所谓“英语思维”,于是学习方法本身便是脱节的。汉语是我们的母语,想将它一下子甩掉不太现实。

早在学校的数据结构与算法课程,弊端就已经显现。算法本身被孤立地灌输给我,要我如何能够面对问题分析问题用算法解决问题?大多的算法都只是跟着实现一遍,也大概就算是学过了。诚然,师傅领进门,修行靠个人,学习本就要靠自己的努力。可我就是缺少指导呀。(吐槽)

回看算法的学习,也应该多参加小比赛,多自己写,才能学会自己写。实践中有其独特而珍贵的经验,而且能为学习方向的调整提供指导。

然而,也常听见一个建议:在做的过程中学。但我曾理解得有些片面,于是钟爱教程而疏于理论,止于模仿而失了变通;于是遇到难题抓脑袋,有一段时间,沉陷在反复的焦虑之中。后来有一次zxl对我说,解决不了,就要想想是不是缺了基础知识,又让我一下子觉得:早该这样。

再看算法学习,总专注于比赛、刷题,而不重视系统性的理论学习,同样不合适。望自警醒。

拼命追着跑还是被匆匆拖着跑,都不太好,得一起跑。

回顾此回顾

要常回顾,以免在歧途上发足狂奔。但我目前有一个大问题,就是我太慢了,相当于在路上花费了太多的时间东张西望。此次比赛回顾,写到这句话,我已经花了8小时。比赛本身也才2小时!

这种习惯对于“常回顾”的目标,必然是极大的负担。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/256860.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python算法题集_二叉树的中序遍历

Python算法题集_二叉树的中序遍历 题94:1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【直接递归】2) 改进版一【函数递归】3) 改进版二【迭代遍历】 4. 最优算法 本文为Python算法题集之一的代码示例 题94: 1. 示例说…

669. 修剪二叉搜索树

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。…

LeetCode、136. 只出现一次的数字【简单,位运算】

文章目录 前言LeetCode、136. 只出现一次的数字【简单,位运算】题目链接与分类思路异或一遍运算 资料获取 前言 博主介绍:✌目前全网粉丝2W,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者、专注于Java后端技术…

拟合案例1:matlab积分函数拟合详细步骤及源码

本文介绍一下基于matlab实现积分函数拟合的过程。采用的工具是lsqcurvefit和nlinfit两个函数工具。关于包含积分运算的函数,这里可以分为两大类啊。我们用具体的案例来展示:一种是积分运算中不包含这个自变量,如下图的第一个公式,也就是说它这个积分运算只有R和Q这两个待定…

【Linux学习】线程互斥与同步

目录 二十.线程互斥 20.1 什么是线程互斥? 20.2 为什么需要线程互斥? 20.3 互斥锁mutex 20.4 互斥量的接口 20.4.1 互斥量初始 20.4.2 互斥量销毁 20.4.3 互斥量加锁 20.4.4 互斥量解锁 20.4.5 互斥量的基本原理 20.4.6 带上互斥锁后的抢票程序 20.5 死锁问题 死锁…

MATLAB|【免费】高比例可再生能源电力系统的调峰成本量化与分摊模型

目录 主要内容 部分代码 结果一览 下载链接 主要内容 程序复现文献《高比例可再生能源电力系统的调峰成本量化与分摊模型》,从净负荷波动的角度出发,建立了调峰成本的量化与分摊模型,构造了无调峰需求的替代场景,将…

matplotlib从起点出发(13)_Tutorial_13_Autoscaling

0 自动放缩 轴上的限制可以手动设置(例如ax.set_xlim(xmin, xmax)),或者Matplotlib可以根据Axes上已有的数据自动设置它们。此种放缩行为有许多选项,如下所述。 我们将从一个简单的折线图开始,显示自动缩放将轴限制扩展到数据的…

Docker Compose实例

目录 一、前提说明 二、简单的Docker容器部署案例 1. Dockerfile 配置 2. docker-compose.yml 配置 3. application-prod.properties 配置 4. pom.xml 配置 5. 上传文件 6. 创建基础Docker镜像 7. docker-compose.yml编排 8. 停止并删除容器编排 三、案例地址 一、前…

在屏蔽任何FRP环境下从零开始搭建安全的FRP内网穿透服务

背景 本人目前在境外某大学读博,校园网屏蔽了所有内网穿透的工具的数据包和IP访问,为了实现在家也能远程访问服务器,就不得不先开个学校VPN,再登陆。我们实验室还需要访问另一个大学的服务器,每次我都要去找另一个大学…

【开源】JAVA+Vue+SpringBoot实现实验室耗材管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 耗材档案模块2.2 耗材入库模块2.3 耗材出库模块2.4 耗材申请模块2.5 耗材审核模块 三、系统展示四、核心代码4.1 查询耗材品类4.2 查询资产出库清单4.3 资产出库4.4 查询入库单4.5 资产入库 五、免责说明 一、摘要 1.1…

微服务OAuth 2.1认证授权可行性方案(Spring Security 6)

文章目录 一、背景二、微服务架构介绍三、认证服务器1. 数据库创建2. 新建模块3. 导入依赖和配置4. 安全认证配置类 四、认证服务器测试1. AUTHORIZATION_CODE(授权码模式)1. 获取授权码2. 获取JWT 2. CLIENT_CREDENTIALS(客户端凭证模式) 五、Gateway1.…

探索Gin框架:Golang Gin框架请求参数的获取

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站https://www.captainbed.cn/kitie。 前言 我们在专栏的前面几篇文章内讲解了Gin框架的路由配置,服务启动等内容。 专栏地址&…

王树森《RNN Transformer》系列公开课

本课程主要介绍NLP相关,包括RNN、LSTM、Attention、Transformer、BERT等模型,以及情感识别、文本生成、机器翻译等应用 ShusenWang的个人空间-ShusenWang个人主页-哔哩哔哩视频 (bilibili.com) (一)NLP基础 1、数据处理基础 数…

PostgreSql与Postgis安装

POstgresql安装 1.登录官网 PostgreSQL: Linux downloads (Red Hat family) 2.选择版本 3.安装 ### 源 yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm ### 客户端 yum install postgresql14 ###…

PgSQL内核特性 - push-based pipeline 执行引擎

PgSQL内核特性 - push-based pipeline 执行引擎 数据库的SQL执行引擎负责处理和执行SQL请求。通常情况下,查询优化器会输出物理执行计划,一般由一系列的算子组成。当前,有两种算子流水线构建方式:1)需求驱动的流水线&a…

Java图形化界面编程—— 基本组件和对话框 笔记

2.5 AWT中常用组件 2.5.1 基本组件 组件名功能ButtonButtonCanvas用于绘图的画布Checkbox复选框组件(也可当做单选框组件使用)CheckboxGroup选项组,用于将多个Checkbox 组件组合成一组, 一组 Checkbox 组件将只有一个可以 被选中…

SpringCloud-Hystrix:服务熔断与服务降级

8. Hystrix:服务熔断 分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免失败! 8.1 服务雪崩 多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服…

PyTorch 2.2大更新!集成FlashAttention-2,性能提升2倍

【新智元导读】新的一年,PyTorch也迎来了重大更新,PyTorch 2.2集成了FlashAttention-2和AOTInductor等新特性,计算性能翻倍。 新的一年,PyTorch也迎来了重大更新! 继去年十月份的PyTorch大会发布了2.1版本之后&#…

从零开始学howtoheap:解题西湖论剑Storm_note

how2heap是由shellphish团队制作的堆利用教程,介绍了多种堆利用技术,后续系列实验我们就通过这个教程来学习。环境可参见从零开始配置pwn环境:从零开始配置pwn环境:从零开始配置pwn环境:优化pwn虚拟机配置支持libc等指…

Uipath 调用Python 脚本程序详解

Python 活动概述 UiPath.Python.Activities 是一个新的活动包,创建它是为了支持直接从工作流运行 Python 脚本和方法。 其包含以下活动: Python 作用域(Python Scope) - 为 Python 活动提供作用域的容器。 加载 Python 脚本(Load Python Script) - 将 P…