diff --git a/docs/.vuepress/public/images/elysia/10.jpg b/docs/.vuepress/public/images/elysia/10.jpg new file mode 100644 index 0000000..126c138 Binary files /dev/null and b/docs/.vuepress/public/images/elysia/10.jpg differ diff --git a/docs/.vuepress/public/images/elysia/11.jpg b/docs/.vuepress/public/images/elysia/11.jpg new file mode 100644 index 0000000..d3b3a9d Binary files /dev/null and b/docs/.vuepress/public/images/elysia/11.jpg differ diff --git a/docs/blog/competition/mati-cup-2024-solutions.md b/docs/blog/competition/mati-cup-2024-solutions.md new file mode 100644 index 0000000..6b6a94c --- /dev/null +++ b/docs/blog/competition/mati-cup-2024-solutions.md @@ -0,0 +1,1888 @@ +--- +title: 码蹄杯 2024 年真题集详解 +createTime: 2026/01/09 16:24:00 +cover: /images/elysia/11.jpg +coverStyle: + layout: left +permalink: /archives/d0ad06b9-d675-461c-a8ce-f47baeeb291d/ +--- + +码蹄杯真题库:2022年-2024年码蹄杯题集 + +原卷链接:2024年 + +青铜的和一些简单的我就不写题解了 + +## MC0301 - 数字大王 + +### 题目链接 +码蹄集OJ-数字大王 + +### 问题描述 +小码哥正在和他的小伙伴们在进行一场编程比赛。这场比赛的主题是“寻找数字大王”,旨在考验各位参赛者对数据的洞察力和编程能力。 + +比赛的规则十分简单:有一个包含n个整数的数列,参赛者需要编写一个程序,从这些数字中找出最大的那个数,称其为“数字大王”。 + +他知道,这不仅仅是一次技术上的挑战,更是一次速度的较量,小马哥深吸一口气,开始了他的操作。 + +### 题目标签 +语言基础:循环语句 + +### 题目难度 +青铜 + +### Python 代码 +```python +n = int(input()) +nums = list(map(int,input().split())) +max_value = nums[0] +for i in range(1,n): + if nums[i] > max_value: + max_value = nums[i] +print(max_value) +# print(max(nums)) +``` + +## MC0302 - 世界守护者 + +### 题目链接 +码蹄集OJ-世界守护者 + +### 问题描述 +在一个数据世界里有这样一个王国,数字们和谐地生活在一起,按照严格的顺序排列,保持着王国的秩序与平衡。 + +然而,最近出现了一个奇怪的现象:一些数字开始随意改变自己的位置,导致王国陷入混乱。国王非常担忧,于是召集了最勇敢、最聪明的守护者——小码哥。 + +小码哥是一个擅长编程和解决数字问题的勇士,他的任务是确保所有的数字都能回到它们正确的位置上。 + +这一天,国王给了小码哥一个特别的任务:有三个叛逆的整数a、b、c逃离了它们应有的位置,打乱了王国的秩序,小码哥需要使用他的编程技巧将它们从小到大排序,以恢复王国的和平。 + +小码哥接受了这个任务,他知道,要完成这个任务,他需要编写一段简短而高效的代码来对这三个数进行排序。 + +### 题目标签 +语言基础:选择结构 + +### 题目难度 +青铜 + +### Python 代码 +```python +# 直接排序 +# nums = list(map(int,input().split())) +# nums.sort() +# print(*nums) +# 选择结构 +# 先把最大的移动到最后面,然后判断两个即可 +x,y,z = map(int,input().split()) +if x > y: + x,y = y,x +if y > z: + y,z = z,y +if x > y: + x,y = y,x +print(x,y,z) +``` + +## MC0303 - 宝藏大冒险 + +### 题目链接 +码蹄集OJ-宝藏大冒险 + +### 问题描述 +传说有一个宝藏在某地,小码哥碰巧拿到了关于这个宝藏的地图,为了快点拿到宝藏于是他选择走直线,起点标记为 1,宝藏的位置标记为 n ,路途中凡是坐标为质数的地方都存在着怪物,但这些怪物如果获得了一点食物就会放行小码哥,请帮助小码哥计算出会遇到多少只怪物,以方便他在出发前准备好充足的食物。 + +### 题目标签 +语言基础:函数 + +### 题目难度 +白银 + +### Python 代码 +```python +# # 循环法判断是否是质数 +# def func1(num): +# for i in range(2,num-1): +# if num % i == 0: +# return False +# return True + +# # 优化后的循环法 +# def func2(num): +# for i in range(2,int(num ** 0.5)+1): +# if num % i == 0: +# return False +# return True + +# n = int(input()) +# count = 0 +# for num in range(2,n+1): +# if func2(num): +# count += 1 +# print(count) + +# 埃氏筛 +# 这里范围 + 1 是为了包含最后一个数 +# 结尾 - 2 是减去 0 和 1 这两个 True +# n = int(input()) +# nums = [True for _ in range(n + 1)] +# for i in range(2,n + 1): +# if nums[i]: +# j = i * 2 +# while j < n + 1: +# nums[j] = False +# j += i +# print(sum(nums)-2) + +# 欧拉筛 +# 比埃氏筛更快 +n = int(input()) +nums = [True for _ in range(n+1)] +primes = [] +for i in range(2,n+1): + if nums[i]: + primes.append(i) + j = 0 + while primes[j] <= n / i: + nums[primes[j] * i] = False + if i % primes[j] == 0: + break + j += 1 +print(len(primes)) +``` + +## MC0304 - 拔河(未完成) + +### 题目链接 +码蹄集OJ-拔河 + +### 问题描述 +小码哥约了一群朋友出去拔河,加上小码哥一共有N个朋友,各自的力量值都不同。 + +这时裁判员要求随机排成一列,排好之后就不能再次改变了。排好后, 他们的力量值分别为为X1,X2,…,Xn。 +然后裁判员对小码哥说,你可以随机选取一段连续的人,你派多少人,另一方就派多少,但是人数不能少于F个。 + +这时候小码哥麻烦了,他不知道如何才能选取一段连续的人且人数不小于F,使得他们的平均力量值最大。 + +### 题目标签 +算法基础:二分 | 三分 + +### 题目难度 +钻石 + +### 解析 +这道题要写出来难度还好,主要是这道题的时间限制为 1 秒,Python 跑不完 + +### Python 代码 +```python +# 基于滑动窗口的暴力破解 +# N,F = map(int,input().split()) +# nums = [] +# for _ in range(N): +# nums.append(int(input())) +# result = 0 +# for window_size in range(F,N+1): +# windows = sum(nums[:window_size]) +# result = max(result,windows // window_size * 1000) +# for i in range(N-window_size): +# windows -= nums[i] +# windows += nums[i+window_size] +# result = max(result,windows // window_size * 1000) +# print(result) + + +# 二分法 +def check(mid): + global N,F + ans = 0 + prefix_sum = nums[:] + for i in range(1,N): + prefix_sum[i] += prefix_sum[i-1] - mid + for i in range(F,N): + ans = min(ans,prefix_sum[i-F]) + if prefix_sum[i] - ans >= 0: + return True + return False + +N,F = map(int,input().split()) +nums = [] +ans = 0 +left,right = 0,1E6 +for _ in range(N): + nums.append(int(input())) +right = max(nums) +while left < right: + mid = left + ( right - left ) // 2 + if check(mid): + left = mid + else: + right = mid - 1 +print(right * 1000) +``` + +## MC0305 - 排名计算 + +### 题目链接 +码蹄集OJ-排名计算 + +### 问题描述 +小码哥经常参加一些程序设计竞赛,他发现在这些竞赛中经常出现并列的排名。 +比如有4名参赛选手的分数分别为50、80、50、30,那么80分的选手就是第1名,50分的两名选手都为第2名,30分的选手为第4名。 +现在请编写一个程序,计算一个选手的名次。 + +### 题目标签 +语言基础:数组 + +### 题目难度 +白银 + +### 解析 +这道题看着可能需要统计相同排名的人,其实不需要。只需要找到排序后的目标成绩第一次出现的位置即可。 + +### Python 代码 +```python +n = int(input()) +scores = list(map(int,input().split())) +m = int(input()) +scores.sort(reverse=True) +ranking = 0 +while scores[ranking] != m: + ranking += 1 +print(ranking + 1) +``` + +## MC0306 - 字符魔鬼 + +### 题目链接 +码蹄集OJ-字符魔鬼 + +### 问题描述 +小码哥有一个字符,表面上看是一个大写字母或者小写字母,但其实他有不为人知的一面。每到特定的时间这个字符就会化身成魔鬼去做坏事,现在小码哥施展法术去看穿它的另一面以提前阻止它,而对于字符的另一面定义为该字符的ascii码。 + +比如:‘A’的ascii码输出是65,‘a’的ascii码输出是97。 + +### 题目标签 +语言基础:基本输入输出 + +### 题目难度 +青铜 + +### Python 代码 +```python +print(ord(input())) +``` + +## MC0307 - 迷宫挑战 + +### 题目链接 +码蹄集OJ-迷宫挑战 + +### 问题描述 +一天,小码哥收到了一封神秘的信件,邀请他参加一场旅行。 + +这场旅行将带他穿越一个有一些传送门的古老迷宫。迷宫由n层组成,下标从1开始。每层都有一个传送门,这些传送门的行为由一个数字k(0≤k≤n)决定。数字k表示当前层可以传送的步数,既可以向上也可以向下。 + +小码哥的目标是从迷宫的第x层出发,到达第y层。然而,传送门的使用有一些限制: +1.如果从当前层向上或向下传送,目标层超出了迷宫的范围,则该传送无效。 +2.每次传送只能按照当前层的kk数值进行移动。 +举例:假设一共7层,且2层的数字是3,那可以从2层到5层,但是无法从2层到-1层。 + +现在,小码哥需要知道从第A层到达第B层至少需要多少次传送。如果无法到达,则返回 -1。 + +### 题目标签 +搜索:BFS + +### 题目难度 +钻石 + +### 解析 +这道题的标签已经写的很清楚了,使用 BFS 广度优先算法来解决这道问题。 + +以初始点开始,每次不断查找所有能去的下一个点,一层层遍历,遍历到目标节点就返回。如果一直为空都没有,那么代表当前节点无法到目标节点,返回 -1即可。注意跳过重复节点,不然会存在循环,以及边界问题。 + +可以在列表前面插入一个空节点,来对齐下标。 + +### Python 代码 +```python +from collections import deque + +def main(): + n, x, y = map(int, input().split()) + steps = [0] + list(map(int, input().split())) + + if x == y: + return 0 + + # 访问过的标记为 True + visited = [False] * (n + 1) + visited[x] = True + queue = deque([x]) + count = 0 + + # BFS 遍历 + while queue: + count += 1 + for _ in range(len(queue)): + current = queue.popleft() + + # 生成上下两个可能楼层 + for delta in (steps[current], -steps[current]): + next_floor = current + delta + + # 楼层有效性检查 + if 1 <= next_floor <= n and not visited[next_floor]: + if next_floor == y: + return count + visited[next_floor] = True + queue.append(next_floor) + + return -1 + + +if __name__ == "__main__": + print(main()) +``` + +## MC0308 - 代课的一天 + +### 题目链接 +码蹄集OJ-代课的一天 + +### 问题描述 +小码哥不是一名计算机专业的学生,但他这天要帮朋友去代上一节程序设计课,课上很不幸被老师指着站起来回答问题,这个问题是:“给你一个字符串,你有什么办法求出大写字母的个数”,小码哥脱口而出:“直接肉眼看着数呗”,话刚说出口小码哥反应过来这是程序设计课,但他不会编程,此时热心肠的你在他旁边想提供帮助,请问你会如何解决这个问题。 + +### 题目标签 +语言基础:字符串 + +### 题目难度 +白银 + +### 解析 +直接比较 ASCII 码就行,比赛的时候要是忘记了 ASCII 码,不用急,直接写个程序看看就行,记住数字转字符是 chr 函数,字符转数字是 ord 函数就好。 + +```python +for i in range(0,128): + print(i,"=>",chr(i)) +``` + +### Python 代码 +```python +content = input() +count = 0 +for chr in content: + if 65 <= ord(chr) <= 91: + count += 1 +print(count) +``` + +## MC0309 - 魔法项链 + +### 题目链接 +码蹄集OJ-魔法项链 + +### 问题描述 +今天是小码妹的生日!小码妹的好朋友久远寺有珠送给她一串魔法项链,如果可以正确使用它的魔力,小码妹施放的魔法威力将会大幅提升。 + +魔法项链由n颗魔法珠子构成,每颗魔法珠子都有自己的魔力值,由于被串成了一条项链,魔法珠子之间产生了共鸣。具体的,两颗珠子产生共鸣后对魔法项链总魔力值的贡献,是两颗珠子魔力值经过按位与运算和按位或运算后结果的加和。在魔法项链中,任意两颗珠子都会产生共鸣。魔法项链的总魔力值是每对魔法珠子共鸣产生魔力值贡献的总和,再加上所有魔法珠子自身魔力值的总和的结果。 + +只有知道了魔法项链的总魔力值,小码妹才能正确使用它的魔力,你能帮帮她吗? + +### 题目标签 +杂项:找规律 + +### 题目难度 +黄金 + +### 解析 +这题是看的评论区的大哥的思路,确实好 + +```python +for i in range(1,6): + for j in range(1,6): + print(f"i = {i}\tj = {j}\ti & j = {i&j}\ti | j = {i|j}\ti&j+i|j = {(i&j) + (i|j)}") +``` + +通过上面的程序可以发现,i&j+i|j 的结果就是 i + j + +题目中说任意两颗珠子都会产生共鸣,即任意一个珠子都会与另外的珠子相加,即每个珠子都会加 n-1 次 + +题目中还说再加上所有魔法珠子自身魔力值的总和,即 n 次。 + +### Python 代码 +```python +n = int(input()) +print(sum(map(int,input().split())) * n) +``` + +## MC0310 - 挑战字符串 + +### 题目链接 +码蹄集OJ-挑战字符串 + +### 问题描述 +有一座被称为“算法之塔”的高塔,传说中能到达塔顶并解决塔顶之谜的人将获得无穷的智慧和力量。然而,要到达塔顶,必须通过试炼,守卫者会提出一个编程挑战。 + +小码哥踏上了攀登算法之塔的旅程。他穿过了森林,越过了山丘,终于来到了塔底。守卫者是一个古老的计算机,它的屏幕上显示着一个挑战:“在你的编程之路上,你会遇到各种各样的字符串。今天的挑战很简单,你需要编写一个程序,将给定的字符串进行倒置,然后输出结果。” + +小码哥接受了挑战,他开始思考如何解决这个问题。 + +### 题目标签 +语言基础:挑战字符串 + +### 题目难度 +青铜 + +### Python 代码 +```python +print(input()[::-1]) +``` + +## MC0311 - 云顶之弈 + +### 题目链接 +码蹄集OJ-云顶之奕 + +### 问题描述 +小码哥最近迷上了一款叫云顶之奕的游戏,然后他要出题了,于是他决定就给大家搞个云顶之奕的题,可是他看到那复杂的机制十分的头疼,要考虑好多东西啊,那就简化一下吧。 + +战棋有着不同的战力,并且三个一样的可以升级(三个一星合成两星,三个两星合成三星,不考虑四星),需要选出最终你要出战的一个战棋,判断他的战斗力能不能比对手的战力强。 + +我们将战棋分为五种,他们一星的战力分别为1 2 3 4 5,二星的战力分别为10 20 30 40 50,三星的战力分别为100 200 300 400 500(例如5 5 5的情况会变成50,也就是说相同战力的三个战棋会自动进化到下一星级)。 + +现在,我们有八个备战席,一个备战席只能放一个战棋。同时还有一个补充战棋队列。备战席战棋确定后,会依次按顺序扫描补充队列,每次扫描一个,看是否有一个战棋能和备战席中的两个战棋发生进化反应。例如(2 2 3 3 4 4 1 1)(1)可以变成(2 2 3 3 4 4 10)。要注意,一次只扫描补充队列的中一个,例如(2 2 3 3 4 4 5 1)(1 1)不能直接合成(2 2 3 3 4 4 5 10)。 + +要注意备战席里,如果凑齐三个同战力的,会自动发生进化。比如(1 1 1 1 1 1 1 1)(1),会连续进化变成(100)。另外,被扫描到的补充队列的战棋,如果没有发生反应,且当前备战席没有满员,那这个战棋会进入到备战席,否则,就会直接略过去。 + +### 题目标签 +算法基础:模拟 + +### 题目难度 +钻石 + +### 解析 +直接模拟即可 + +### Python 代码 +```python +# 执行合并操作 +def func(queue:list) -> bool: + for i in range(2,len(queue)): + # 判断是否能够合并 + if queue[i] == queue[i-1] == queue[i-2] and queue[i] < 100: + value = queue[i] + for _ in range(3): + queue.remove(value) + queue.append(value*10) + # 合并之后,可能存在还能合并的情况,继续合并 + func(queue) + return True + return False + +queue = list(map(int,input().split())) +n = int(input()) +deck = list(map(int,input().split())) +m = int(input()) + +# 遍历牌堆 +for brand in deck: + queue.append(brand) + queue.sort() + if not func(queue) and len(queue) == 9: + queue.remove(brand) +queue.sort() +print("YES YES YES" if queue[-1] >= m else "NO NO NO") +``` + +## MC0312 - 死亡名单 + +### 题目链接 +码蹄集OJ-死亡名单 + +### 问题描述 +职业杀手小码哥接到了一个任务,去暗杀名单上的人,名单里共有 n 个人,编号为 a1∼an​ ,但其中有 m 个人是小码哥的朋友,所以 he 会把他朋友划掉并伪造新的名单,注意每划掉一个人就要伪造一份名单,所以小码哥一共要操作m次,并且每次操作的名单都是上一份伪造的名单,现在给出每次操作时小码哥朋友的位置x,然后划掉ax,请问最后的名单中还剩哪些人。 + +### 题目标签 +语言基础:数组 + +### 题目难度 +白银 + +### 解析 +直接删除指定位的数字即可 + +### Python 代码 +```python +n = int(input()) +nnums = list(map(int,input().split())) +m = int(input()) +mnums = list(map(int,input().split())) + +for m in mnums: + nnums.pop(m-1) +print(" ".join(map(str,nnums))) +``` + +## MC0313 - 最佳邻居 + +### 题目链接 +码蹄集OJ-最佳邻居 + +### 问题描述 +有一条环形街道,街道上串行着有 n 个房子,且第一个房子和最后一个房子相邻形成一个环。每个房子面前都有一个娱乐场地,可以打篮球、羽毛球等等。 + +有天小码哥来这里玩,他喜欢热闹一点所以会前往人最多的场地,这时他突然想到个问题,如果有 4 个相邻的房子前面的场地人数加起来是最多的,那么这 4 家人就称之为最佳邻居。 + +现在给出 n 个房子前面的场地人数,请找出最佳邻居,只要最多的场地人数之和以及起始位置就行了。 + +### 题目标签 +语言基础:循环结构 + +### 题目难度 +白银 + +### 解析 +把前三个加到末尾或求余的方法都可以 + +### Python 代码 +```python +# 直接把前三个加到末尾 +# n = int(input()) +# nums = list(map(int,input().split())) +# nums += nums[:3] +# max_people = windows = sum(nums[:4]) +# result = 0 +# for i in range(n-1): +# windows -= nums[i] +# windows += nums[i+4] +# if windows > max_people: +# max_people = windows +# result = i + 1 +# print(max_people) +# print(result+1) + +# 求余法 +n = int(input()) +nums = list(map(int,input().split())) +max_value = windows = sum(nums[:4]) +result = 0 +for i in range(n): + windows -= nums[i] + windows += nums[(i + 4) % n] + if windows > max_value: + max_value = windows + result = i + 1 +print(max_value) +print(result + 1) +``` + +## MC0314 - 数字小王 + +### 题目链接 +码蹄集OJ-数字小王 + +### 问题描述 +之前小码哥和他的小伙伴们进行了一场“寻找数字大王”的编程比赛,现在又有一场“寻找数字小王”的比赛,顾名思义就是在数列中找出最小的那个数,称其为“数字小王”。 + +这场比赛的主题是“寻找数字大王”,旨在考验各位参赛者对数据的洞察力和编程能力。 + +小码哥已经赢得了上次的冠军,现在他还想再次挑战。 + +### 题目标签 +语言基础:循环结构 + +### 题目难度 +青铜 + +### Python 代码 +```python +n = int(input()) +print(min(map(int,input().split()))) +``` + +## MC0315 - 判断三个正整数是否相邻 + +### 题目链接 +码蹄集OJ-判断三个正整数是否相邻 + +### 问题描述 +给出3个正整数,判断这3个整数是否相邻,是输出“TRUE”,否则输出“FALSE”。 + +### 题目标签 +语言基础:选择结构 + +### 题目难度 +青铜 + +### Python 代码 +```python +x,y,z = map(int,input().split()) +if x > y: + x,y = y,x +if y > z: + y,z = z,y +if x > y: + x,y = y,x + +if z - y == y - x == 1: + print("TRUE") +else: + print("FALSE") +``` + +## MC0316 - 众符 + +### 题目链接 +码蹄集OJ-众符 + +### 问题描述 +对于一个数列,里面出现次数最多的数字就称为“众数”,现在小码哥想进行延伸,一个字符串中出现次数最多的字符就称为“众符”。 + +现在有一个由小写字母组成的字符串,输出它的“众符”。 + +如果有多个小写字母出现的次数一样多,则输出ASCII码值最小的那个字母。 + +### 题目标签 +语言基础:字符串 + +### 题目难度 +白银 + +### 解析 +统计,然后返回最大的数的第一次出现的位置即可 + +### Python 代码 +```python +count = [0] * 26 +for ch in input(): + count[ord(ch)-97] += 1 +print(chr(97 + count.index(max(count)))) +``` + +## MC0317 - 传火之路(未完成) + +### 题目链接 +码蹄集OJ-传火之路 + +### 题目标签 +搜索:BFS + +### 题目难度 +钻石 + +## MC0318 - 奇偶分家 + +### 题目链接 +码蹄集OJ-奇偶分家 + +### 问题描述 +在一个由数字构成的奇幻世界里,居住着一群热爱编程和算法的生物,它们被称为“编码精灵”。这个世界被两个强大的国度所统治:奇数王国和偶数王国。奇数王国以其居民的独立和不羁著称,而偶数王国则以其和谐与平衡闻名。这两个国度之间存在着一种神秘的平衡,使得整个世界得以和平共存。 + +在这个世界的中心,有一座被称为“编程塔”的古老结构,它是所有编码精灵学习和挑战自我的地方。每年,编程塔都会举办一次盛大的比赛,吸引来自奇数王国和偶数王国的年轻精灵们参加。比赛的目的是解决一系列复杂的问题,以考验他们的编程技能和逻辑思维。 + +今年的比赛主题是“数字的和谐”,组织者提出了一个看似简单却蕴含深意的题目:“给定 n 个非负整数,请统计奇数和偶数各有多少个?”这个问题要求参赛者不仅要编写出高效的算法,还要理解数字的本质和它们之间的关系。 + +小码哥是一位来自奇数王国的年轻编码精灵,他因其出色的编程能力和对算法的深刻理解而闻名。他决定接受这个挑战,不仅为了证明自己的实力,也为了增进奇数王国与偶数王国之间的友谊和理解。 + +比赛当天,小码哥带着他的魔法键盘来到了编程塔。他深吸一口气,然后手指在键盘上飞快地舞动… + +### 题目标签 +语言基础:循环结构 + +### 题目难度 +青铜 + +### Python 代码 +```python +n = int(input()) +nums = list(map(int,input().split())) +x = sum([num % 2 for num in nums]) +print(x,n-x) +``` + +## MC0319 - 小码哥幸运日 + +### 题目链接 +码蹄集OJ-小码哥幸运日 + +### 问题描述 +数字 2 是小码哥的幸运数字,小码哥认为他从出生开始算的天数中凡是带 2 的一定是他的幸运日,现在给出两个数字 L 和 R ,即从他出生开始算的第 L 天到 第 R 天,请求出区间 [L,R][L,R] 的所有天数幸运值之和。 + +对于幸运值的定义:2 出现的次数之和。 + +比如给定区间 [2, 22],数字2在数2中出现了1次,在数12中出现1次,在数20中出现1次,在数21中出现1次,在数22中出现2次,所以数字2在该区间内一共出现了6次,也就是说该区间的幸运值之和为6。 + +### 题目标签 +语言基础:函数 + +### 题目难度 +白银 + +### 解析 +直接遍历然后统计 + +### Python 代码 +```python +# 直接遍历然后统计 +L,R = map(int,input().split()) +print(sum([str(ch).count("2") for ch in range(L,R+1)])) +``` + +## MC0320 - 狠狠地对字符串做你想做的事吧 + +### 题目链接 +码蹄集OJ-狠狠地对字符串做你想做的事吧 + +### 问题描述 +对一个字符串S ,有以下两种操作: +• 将子串 01 替换为 1 +• 将子串 10 替换为 0 + +总共t组数据,每组的SS都是一个给定长度为n的 01 串。 + +求每组数据中,S一共有多少个子串,能经过若干次操作,变成长度为1的字符串。 + +### 题目标签 +杂项:找规律 + +### 题目难度 +黄金 + +### 解析 +字符串的最后两位如果相同的话,无法得到结果,剩下的情况都可以 + +### Python 代码 +```python +for _ in range(int(input())): + N = int(input()) + S = input() + for i in range(N): + if i > 0 and S[i] != S[i-1]: + N += i + print(N) +``` + +## MC0321 - 亲近数 + +### 题目链接 +码蹄集OJ-亲近数 + +### 问题描述 +数学上把2的x次方叫2的x次幂,如4、8、16等,而小码哥定义了一个数字的亲近数:距离最近的那个2的幂。 + +对于数字 n ,请找出他的亲近数。 + +注意如果有两个距离相同,输出小的数。 + +### 题目标签 +语言基础:选择结构 + +### 题目难度 +白银 + +### 解析 +直接循环查找,然后判断距离那个更近 + +### Python 代码 +```python +n = int(input()) +i = 0 +while 2 ** i < n: + i += 1 +if 2 ** i - n > n - 2 ** ( i - 1 ): + print(2 ** ( i - 1 )) +else: + print(2 ** i) +``` + +## MC0322 - 数组搜索 + +### 题目链接 +码蹄集OJ-数组搜索 + +### 问题描述 +现在有一个长度为n的非严格单调递增的数组,小码哥希望你能根据他的m条指令来进行相应的搜索查找,你能够帮他完成吗。如果小码哥说‘L’和一个数字X,那么请你找出这列数组中第一次出现X他的数组下标,如果小码哥说‘R’和一个数字X,那么请你找出这列数组中最后一次出现这个X他的数组下标。如果没有这个数,请你输出‘-1’; +注意:下标从0开始! + +### 题目标签 +语言基础:数组 + +### 题目难度 +白银 + +### 解析 +预处理、或者二分查找,都可以 + +### Python 代码 +```python +# 预处理 +# n,m = map(int,input().split()) +# nums = [None] * 100001 + +# for i,num in enumerate(list(map(int,input().split()))): +# if nums[num] is None: +# nums[num] = [i,i] +# else: +# nums[num][1] = i + +# for _ in range(m): +# operator,num = input().split() +# if nums[int(num)] is None: +# print(-1) +# else: +# print(nums[int(num)][0] if operator == "L" else nums[int(num)][1]) + +def find_left(nums, target): + low, high = 0, len(nums) + while low < high: + mid = (low + high) // 2 + if nums[mid] < target: + low = mid + 1 + else: + high = mid + return low + +def find_right(nums, target): + low, high = 0, len(nums) + while low < high: + mid = (low + high) // 2 + if nums[mid] > target: + high = mid + else: + low = mid + 1 + return low - 1 + +n,m = map(int,input().split()) +nums = list(map(int,input().split())) +for _ in range(m): + operator,num = input().split() + res = find_left(nums,int(num)) if operator == 'L' else find_right(nums,int(num)) + print(res if nums[res] == int(num) else -1) +``` + +## MC0323 - 恢复乘法表 + +### 题目链接 +码蹄集OJ-恢复乘法表 + +### 问题描述 +小码哥拥有一台神奇的计算机器,这台机器能够解答任何形式的问题,只要按照特定的格式输入,它就能给出精确的答案。 + +有一天,世界上所有人都中了一种奇怪病毒,这种病毒被称为“混乱代码”,它使得人们脑中的九九乘法表变得错乱不堪,这导致一系列问题,世界开始暴乱。 + +为了恢复秩序,小码哥决定挺身而出,利用它的智慧和那台神奇的计算机器,一一校正那些被病毒影响的算式,让它们恢复正常。 + +九九乘法表中是这样的形式:a∗b=,这个算式看似简单,却因为混乱代码的影响,无法得出正确的结果。小码哥将1到9的数字可重复的两两组合输入到它的计算机器中,按下了等号键。机器发出了光芒,显示出了正确的结果。随着这个结果的出现,人们的混乱代码开始逐渐消散。 + +请你模拟这台机器,每当拿到aa和bb的值后,就按特定的格式输出结果。 + +### 题目标签 +语言基础:字符串 + +### 题目难度 +青铜 + +### Python 代码 +```python +a,b = input().split("*") +a = int(a) +b = int(b[:-1]) +print(a*b) +``` + +## MC0324 - 完美镶嵌点 + +### 题目链接 +码蹄集OJ-完美镶嵌点 + +### 问题描述 +小码哥有一个无序数列,他知道插入某个数字xx 就能使这段数据变得优美,但是这个数字必须加在合适的位置。合适的位置是指,保持原来的数列每个数的相对位置不变,将x插入到这个数列里第一个不小于它的数字前面。如果所有的数都比x小,则将x放到队尾。 + +请输出插入元素后的数列。 + +### 题目标签 +语言基础:选择结构 + +### 题目难度 +白银 + +### Python 代码 +```python +n,x = map(int,input().split()) +nums = list(map(int,input().split())) +i = 0 +while i < n and nums[i] < x: + i += 1 +nums.insert(i,x) +print(*nums) +``` + +## MC0325 - 最优灌溉系统的设计(未完成) + + +## MC0326 - 奇怪的数列 + +### 题目链接 +码蹄集OJ-奇怪的数列 + +### 问题描述 +找一个数列通项公式的方法有很多种,但小码哥遇到了一个看似很有规律但很难总结出通项公式的数列,你知道该如何用编程的方式得到该数列的第 n 项吗? + +这个数列是:1,2,2,3,3,3,4,4,4,4… + +### 题目标签 +语言基础:循环结构 + +### 题目难度 +白银 + +### 解析 +1 个 1 , 2 个 2 , 3 个 3... + +这就是一个等差数列,通过等差数列求和公式可以快速计算到第i个数字的时候,当前数列一共有多长,那么只要到当前数列的长度大于 n 的时候,当前的数字i就是结果 + +### Python 代码 +```python +n = int(input()) +i = 1 +while i/2 * (1+i) < n: + i += 1 +print(i) +``` + +## MC0327 - 神秘的仪式 + +### 题目链接 +码蹄集OJ-神秘的仪式 + +### 问题描述 +在成功地恢复了数据世界的秩序之后,小码哥被赋予了新的任务。在王国中,存在一个古老的传统——数字比较仪式,这个仪式对于保持王国内部的和谐至关重要,因为它确保了数字之间的关系得到正确的处理和维护。 + +在这个仪式中,有三个数字将会被选出来进行一次比较。如果前两个数字之和大于第三个数字,那么它们会被认为是“和谐”的,王国将会迎来和平与繁荣。如果不是这样,整个王国将陷入一段不确定的未来。 + +有一天,国王召集小码哥,告诉他有三个关键的整数 a,b,c 需要进行比较。小码哥知道这不仅仅是一个简单的数学问题,而是关乎整个王国命运的重大任务。他必须使用他的编程技能来确定这三个数字是否符合“和谐”的原则。 + +如果符合“和谐”的原则,那么就输出 “yes”,否则就输出“no”。 + +### 题目标签 +语言基础:选择结构 + +### 题目难度 +青铜 + +### Python 代码 +```python +x,y,z = map(int,input().split()) +print("yes" if x + y > z else "no") +``` + +## MC0328 - 小码哥的式子 + +### 题目链接 +码蹄集OJ-小码哥的式子 + +### 问题描述 +小码哥从小便对计算机充满好奇,总是喜欢探索未知的程序。通过不懈努力,他逐渐掌握了各种编程语言,他发现了一个真理:在编程的世界里,即使是最简单的操作也可能蕴含着深远的意义。小码哥意识到,a*b%c 不仅仅是一个简单的数学运算,它是对计算本质的探索,是对算法之美的一种颂歌。 + +他的智慧被所有程序员所赞颂,同时也激励着一代又一代的编程新手,去探索那些未知的领域。 + +从此以后,小码哥的名字成为了智慧的象征,而那个简单的算式 a*b%c 提醒着人们不断追求知识的旅程永无止境。 + +现在已经知道了若干组 a,b,c 三个整数,请求出每组 a*b%c 的值。 + +### 题目标签 +语言基础:公式与计算 + +### 题目难度 +青铜 + +### Python 代码 +```python +while True: + try: + x,y,z = map(int,input().split()) + print(x*y%z) + except: + break +``` + +## MC0329 - 都市路径 + +### 题目链接 +码蹄集OJ-都市路径 + +### 问题描述 +小码哥住在一个繁华的都市中,这个城市如同一个庞大的图结构G,街道就像有向图中的边,而大厦、公园和广场则像是图中的顶点。在这个城市里,交通拥堵是一个普遍的问题,每个人都渴望找到最快捷的路线来节省宝贵的时间。 + +有一天,城市的交通规划局面临了一个棘手的问题:他们需要为一项重大活动制定最优的交通流线,确保参与者能够从中心会场快速到达各个目的地。为了解决这个问题,他们决定求助于小码哥。 + +小码哥被指派了一项任务:利用编程技术,找出从中心会场(编号为1)到城市内所有地点的最短路路径,以便在活动当天指导交通。如果无法直接到达某个地点,那么应该标记出不可达的距离值-1。 + +### 题目标签 +图论:BFS + +### 题目难度 +黄金 + +### 解析 +迪杰特拉斯算法,再存储一下叶子节点即可 + +### Python 代码 +```python +n = int(input()) +nodes = [-1] * ( n + 1 ) +nodes[1] = 0 +table = [[]] * ( n + 1 ) +for _ in range(n): + u,k,*v = map(int,input().split()) + table[u] = v +queue = [1] +history = set(queue) +while queue: + u = queue.pop(0) + for v in table[u]: + nodes[v] = nodes[u] + 1 if nodes[v] == -1 else min(nodes[v],nodes[u] + 1) + if v not in history: + queue.append(v) + history.add(v) + +for i in range(1,n+1): + print(i,nodes[i]) +``` + +## MC0330 - 奇怪的数 + +### 题目链接 +码蹄集OJ-奇怪的数 + +### 问题描述 +小码哥很喜欢研究数字,这天小码妹问了他一个问题:“请问一个数字的各个位数上的数字之和为 10 的数有什么性质吗”,小码哥没找到关于这种数字的资料,于是自行将这种数字命名为奇怪的数,并且他还引申出了一个新问题:从 1 到 n 的整数中有多少个数字是奇怪的的数。 + +比如19、28、37、127都是符合条件的数。 + +### 题目标签 +语言基础:函数 + +### 题目难度 +白银 + +### Python 代码 +```python +n = int(input()) +cnt = 0 +for i in range(1,n+1): + if sum(map(int,str(i))) == 10: + cnt += 1 +print(cnt) +``` + +## MC0331 - 打工人 + +### 题目链接 +码蹄集OJ-打工人 + +### 问题描述 +随着工作的熟练,小码哥办事的效率也随着时间的推移而提高。在第1天,他只能完成1项任务,接下来的2天(第2到第3天),他每天可以完成2项任务,再接下来的3天(第4到第6天),他每天可以完成3项任务… 以此类推,再接下来的n天可以每天完成n项任务。 + +小码哥现在从第1天开始做事,希望聪明的你可以帮忙计算一下,在给定的[L,R]天数区间的时间内,他一共完成了几项任务。 + +### 题目标签 +算法基础:前缀和|差分 + +### 题目难度 +钻石 + +### 解析 +第一种评论区有对应的 C++ 代码,原理是一样的,都是通过二分查找对应的值,但是最后的计算公式好像不太一样,都能过。 + +第二种是一个朋友解出来的 + +这里取 + 号 + +### Python 代码 +```python +def Tn(x): + return x * (x + 1) // 2 + +def Sn(x): + return x * (2 * x + 1) * (x + 1) // 6 + +def sol(x): + left, right, k = 1, 1E9, 1 + while right >= left: + mid = (left + right) // 2 + if Tn(mid) >= x: + right = mid - 1 + k = mid + else: + left = mid + 1 + return k + +def func(i): + x = sol(i) + return Sn(x-1) + ( i - Tn(x-1) ) * x + +for _ in range(int(input())): + L,R = map(int,input().split()) + L,R = func(L-1),func(R) + print(int(R - L)) + +# import math +# a = int(input()) +# for i in range(a): +# b=list(map(int,input().split())) +# b[0] -= 1 +# h = [] +# for j in b: +# c = 0 +# e = int(math.sqrt(2*j+0.25)-0.5) +# c += e*(e+1)*(2*e+1)//6 +# z = j-e*(e+1)//2 +# c += z*(e+1) +# h.append(c) +# print(h[1]-h[0]) +``` + +## MC0332 - 简单的进制转换 + +### 题目链接 +码蹄集OJ-简单的进制转换 + +### 问题描述 +众所周知计算机底层采用二进制进行状态表示,而十进制更符合人类的思想,现在有一个二进制串,请把它转换成十进制。 + +### 题目标签 +语言基础:字符串 + +### 题目难度 +白银 + +### Python 代码 +```python +bin_st = input() +print(int(bin_st,2)) +``` + +## MC0333 - 时间转换 + +### 题目链接 +码蹄集OJ-时间转换 + +### 问题描述 +某天,小码哥收到了一个神秘的挑战。挑战来自一个古老的时钟守护者,这个守护者负责维护一个庞大的时间库,里面存储了从宇宙诞生以来的所有时间记录。然而,由于年代久远,这些记录都是以秒为单位存储的,这让守护者感到十分头疼,因为现代人更习惯使用时分秒的格式来读取时间。 + +守护者听说小码哥擅长处理各种数据转换问题,便向他发起挑战:如果小码哥能够编写出一个程序,将任意给定的秒数转换为人们习惯的 x : x : x 格式,守护者将授予他“时间转换大师”的称号,并允许他访问时间库中的秘密知识。 + +小码哥接受了这个挑战。他开始沉思,如何能够高效地完成这个转换。他知道,一小时有3600秒,一分钟有60秒。所以,他需要编写一个程序,首先计算出给定秒数包含多少小时,然后是分钟,最后是剩余的秒数。 + +### 题目标签 +语言基础:公式与计算 + +### 题目难度 +青铜 + +### Python 代码 +```python +n = int(input()) +h = n // 3600 +m = n % 60 +f = n % 3600 // 60 +print(f"{h}:{f}:{m}") +``` + +## MC0334 - P 序列(未完成) + +## MC0335 - 迷宫的秘密 + +### 题目链接 +码蹄集OJ-迷宫的秘密 + +### 问题描述 +有一片被数字精灵守护的神秘森林中隐藏着一座古老的迷宫,迷宫的每一道墙壁上都刻满了数字。相传,只有找到所有特殊的数字,才能解开迷宫的秘密。 + +小码哥是一位热爱编程和算法的年轻探险家,他听说了这个数字迷阵的传说,决定踏上寻找这个神秘数字的旅程。 + +迷宫的入口处,一块石碑上刻着一行提示:“寻找那个独特的存在,它将指引你走向真理。”小码哥知道,这是迷宫给他的第一个线索。 + +他开始在迷宫中穿梭,每走过一段路,就会遇到一堵墙,墙上是一串长长的数字序列。小码哥快速地分析每一组数字,寻找那个特殊的数。他知道,这个数不会出现在序列的开始或结束。 + +日复一日,小码哥在迷宫中不断地尝试和思考。他遇到了许多挑战,有时甚至陷入僵局,但他没有放弃。他相信,只要坚持逻辑和算法,最终会找到答案。 + +终于,在一个阳光明媚的下午,小码哥站在一堵墙前,眼前的数字序列似乎在对他微笑。他的目光锁定在了序列中间的一个数字上——它比它左边和右边的数字都要大。小码哥激动地跳了起来,他知道,这就是他寻找的答案! + +现在小码哥已经整合出了所看到的 n 个数,请帮他找出所有特殊的数。 + +### 题目标签 +语言基础:循环结构 + +### 题目难度 +青铜 + +### Python 代码 +```python +n = int(input()) +nums = list(map(int,input().split())) +for i in range(1,n-1): + if nums[i-1] < nums[i] and nums[i] > nums[i+1]: + print(nums[i]) +``` + +## MC0336 - 灵异空间 + +### 题目链接 +码蹄集OJ-灵异空间 + +### 问题描述 +在一个一维空间中,初始散布着 N 个数字(可以理解为数组),魔法师小码哥想通过 M 操作改变这些数字的顺序,具体的操作是这样的:先选定一个左端点 L 和一个右端点 R ,然后把区间 [L,R] 里的数字进行反转,求最后这个空间的所有数字顺序是怎样的。 + +### 题目标签 +语言基础:循环结构 + +### 题目难度 +白银 + +### 解析 +直接模拟即可 + +### Python 代码 +```python +N,M = map(int,input().split()) +nums = list(map(int,input().split())) + +for _ in range(M): + L,R = map(int,input().split()) + nums = nums[:L-1] + nums[L-1:R][::-1] + nums[R:] +print(*nums) +``` + +## MC0337 - 寻找质因子 + +### 题目链接 +码蹄集OJ-寻找质因子 + +### 问题描述 +作为一个数学天才,小码哥经常提出一些关于数论的问题,今天他又想出了一道关于质数的问题:对于一个正整数 n ,找出它的所有质因子,请问你会如何解决。 + +### 题目标签 +语言基础:循环结构 + +### 题目难度 +白银 + +### Python 代码 +```python +n = int(input()) +factor = 2 +while factor ** 2 <= n: + while n % factor == 0: + print(factor) + n //= factor + factor += 1 +if n > 1: + print(n) +``` + +## MC0338 - 多项式输入 + +### 题目链接 +码蹄集OJ-多项式输入 + +### 问题描述 +一元n次多项式可用如下的表达式表示: +f(x)=anxn+an−1xn−1+…+a1x+a0​ + +其中a0≠0,aixi 称为i次项,ai​称为i次项的系数。给出一个一元多项式各项的次数和系数,请按照如下规定的格式要求输出该多项式: +1.多项式中自变量为x,从左到右按照次数递减顺序给出多项式; +2.多项式中只包含系数不为0的项; +3.如果多项式最高次项系数为正,则多项式开头不出现“+”号;如果最高次项系数为负,则多项式以“-”号开头;如果最高次项系数为0,且次高项系数为正,则次高项开头不出现“+”号;以此类推; +4.对于不是第一个输出的项,以“+”号或者“-”号连接此项与前一项,分别表示此项系数为正或者系数为负。紧跟一个正整数,表示此项系数的绝对值(如果一个高于0 次的项,其系数的绝对值为1,则无需输出1)。如果x的指数大于1,则接下来紧跟的指数部分的形式为“x^b”,其中b为x的指数;如果x的指数为1,则接下来紧跟的指数部分形式为“x”;如果x的指数为0,则仅需输出系数即可; +5.多项式中,多项式的开头、结尾不含多余的空格。 + +### 题目标签 +算法基础:模拟 + +### 题目难度 +黄金 + +### 解析 +按照题目中的描述,一点点写判断语句即可。 +可以全部都写上符号,最后再判断是否要去掉开始的符号 + +### Python 代码 +```python +n = int(input()) +nums = list(map(int,input().split())) +result = "" +for i in range(n): + if nums[i] == 0: + continue + result += "+" if nums[i] > 0 else "-" + result += "x" if abs(nums[i]) == 1 else f"{abs(nums[i])}x" + if n - i > 1: + result += f"^{n-i}" +if nums[-1] != 0: + result += f"+{nums[-1]}" if nums[-1] > 0 else f"{nums[-1]}" +print(result[1:] if result[0] == "+" else result) +``` + +## MC0339 - 出去玩 + +### 题目链接 +码蹄集OJ-出去玩 + +### 问题描述 +小码哥想去找女朋友玩,出行方式有两种,要么坐地铁要么坐公交车,小码哥每次都是早上去晚上回来,早上坐公交车过去的费用是A元,晚上坐公交车回来的费用是B元;早上坐地铁过去的费用是C元,晚上坐地铁回来的费用是D元,因为小码哥非常穷所以希望尽可能的省钱,于是他拜托万能的你写一个程序,帮他计算出,出去回来的费用最少是多少? + +### 题目标签 +语言基础:公式与计算 + +### 题目难度 +白银 + +### Python 代码 +```python +A,B,C,D = map(int,input().split()) +print(min(A,C) + min(B,D)) +``` + +## MC0340 - 矩阵虫 + +### 题目链接 +码蹄集OJ-矩阵虫 + +### 问题描述 +“回到坐标上来,空间中有许多坐标在穿行,如同母世界的天空中飞翔的矩阵虫。”——《三体III·掩体纪元67年,银河系猎户旋臂》 + +对于矩阵虫的具体形象无从查证,也许是代指舰队,也可能是一种群居昆虫。 + +矩阵虫有一个描述参数 n,可以构成一个 n∗n 的矩阵,该矩阵每一行的数字依次为 1,2,3,4…n + +### 题目标签 +算法基础:模拟 + +### 题目难度 +青铜 + +### Python 代码 +```python +n = int(input()) +st = "".join([str(i) for i in range(1,n+1)]) +for _ in range(n): + print(st) +``` + +## MC0341 - 与 7 无关数 + +### 题目链接 +码蹄集OJ-与7无关数 + +### 问题描述 +纵观数学史上,许多大数学家都喜欢研究一些具备特有属性的数字,小码哥也想来凑凑热闹,他定义了一种“与7有关数”,这种数需要满足这两个条件之一: +1.能被7整除; +2.数位中至少有一位是7。 + +比如14能被7整除,17有一位为7,这两个数都是与7有关的数。 + +很明显“与7无关数”就是上面两种条件都不满足,现在给一个参数 n ,求出1~n中所有“与7无关数”的总和。 + +### 题目标签 +语言基础:函数 + +### 题目难度 +白银 + +### Python 代码 +```python +n = int(input()) +count = 0 +for i in range(1,n+1): + if i % 7 == 0 or "7" in str(i): + continue + count += i +print(count) +``` + +## MC0342 - 小纸条 + +### 题目链接 +码蹄集OJ-小纸条 + +### 问题描述 +小码哥和小码妹是好朋友,此时他们正在上课,但是他们又想聊天,只能通过传递小纸条的方式和对方说话,由于小码哥和小码妹间隔很远,所以只能通过中间的同学帮忙传递,但是小码哥不想在传递时候被别人知道传递的内容是什么,于是和小码妹约定好了一个加密方法,这个方法只有他们两人知道,所以他们传递通过此方法加密的信息也只有他们知道。 + +加密方法:把小码哥想传递的话看成是一个字符串A比如是“abac”,那么首先小码哥会提取出字符串A的所有长度为2的子串并且按照从左到右的顺序列出也就是 “ab”,“ba”,“ac”,然后将提取出来的子串按照从左到右的顺序拼接起来就是最终加密的字符串B“abbaac”。 + +### 题目标签 +语言基础:字符串 + +### 题目难度 +白银 + +### 解析 +每两个之间会存在一个重复字符,剔除即可 + +### Python 代码 +```python +B = input() +print(B[0] + "".join(B[i] for i in range(1,len(B)-2,2)) + B[-1]) +``` + +## MC0343 - 小码哥的滞销(未完成) + +## MC0344 - 扩建鱼塘问题 + +### 题目链接 +码蹄集OJ-扩建鱼塘问题 + +### 问题描述 +小码哥是一个热爱编程的程序员,他总是喜欢用编程来解决生活中的问题。 + +有一天,他接到了一个有趣的任务:帮助村民们扩建鱼塘。 + +这个鱼塘位于村庄的中心地带,是村民们养鱼的重要场所。鱼塘的尺寸为m * n平方米,由于鱼塘的形状是矩形,所以村民们希望能够将其扩建为正方形,以便更好地管理和使用。现在需要看,扩建最少增加多少面积。 + +小码哥决定利用他的编程技巧来解决这个问题。 + +### 题目标签 +语言基础:公式与计算 + +### 题目难度 +青铜 + +### Python 代码 +```python +m,n = map(int,input().split()) +print(max(m,n) * max(m,n) - m * n) +``` + +## MC0345 - 小兔子乖乖,把门开开(未完成) + + +## MC0346 - 利刃华尔兹 + +### 题目链接 +码蹄集OJ-利刃华尔兹 + +### 问题描述 +小码哥很喜欢玩无双剑姬,为此他苦练剑术,终于神功大成…现在给出小码哥擅长绝技的简化版技能描述以及一种增加伤害的机制,你需要计算只使用技能的情况下能否击杀对方。 +技能伤害由基础攻击力和额外攻击力加成决定,在本题中假设该英雄由四个技能组成,每个技能只能使用一次: +1.技能破空斩,造成伤害值为100%基础攻击力+90%额外攻击力。例如,基础攻击力为100,额外攻击力也为100时,能造成190伤害. +2.技能夺命连刺,连续攻击两次,分别造成伤害值为100%基础攻击力、100%基础攻击力+200%额外攻击力。 +3.技能无双挑战,以华丽的进攻方式连续进攻四次,每次造成伤害值为100%基础攻击力+500%额外攻击力。 +4.技能引燃,瞬间造成固定500的伤害。 +注意,用以上四个技能对敌方每造成一次伤害,都会使额外攻击力增加20%。例如:基础攻击力100,额外攻击力100,用2技能,第一刀造成100的伤害,第二刀造成100+240的伤害。如果不使用2技能改为使用3技能则会造成100+500、100+600、100+720、100+864四段伤害。 +另外,题目中的连续攻击代表不能在技能期间使用其他技能,比如2技能砍一刀后不能在砍第二刀前使用其他任何技能。 + +### 题目标签 +算法基础:模拟 + +### 题目难度 +黄金 + +### 解析 +先放引燃,然后一个个放就行,记得要小数 + +### Python 代码 +```python +a,b,k = map(float,input().split()) + +ans = 500 +b *= 1.2 + +ans += a + b * 0.9 +b *= 1.2 + +ans += a +b *= 1.2 +ans += a + b * 2 +b *= 1.2 + +for _ in range(4): + ans += a + b * 5 + b *= 1.2 + +if ans >= k: + print("You have slain an enemy") +else: + print("You have been slain") +``` + +## MC0347 - 数羊数钱数星星 + +### 题目链接 +码蹄集OJ-数羊数钱数星星 + +### 问题描述 +小码哥上课很困,过了一会儿,他意识到他得数数,不能入睡。 + +小码哥的大脑反应灵敏,仿佛真实地看到了他数过的一个又一个数。他开始注意每一个数码(0到9):每一个数码在计数的过程中出现过多少次? + +给出两个整数M和N,求在序列[M,M+1,M+2,…,N−1,N]中每一个数码出现了多少次? + +### 题目标签 +算法基础:模拟 + +### 题目难度 +白银 + +### 解析 +范围不大,直接遍历然后统计即可 + +### Python 代码 +```python +M,N = map(int,input().split()) +cnt = {"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0} +for number in range(M,N+1): + for ch in str(number): + cnt[ch] += 1 +print(*cnt.values()) +``` + +## MC0348 - 出题人的烦恼(未完成) + +### 题目链接 +码蹄集OJ-出题人的烦恼 + +### 问题描述 +小码哥正在出题,总所周知,高难度级别题目的数据是十分不好造的。小码哥一直想造出一棵符合条件的树,但由于技术不好,小码哥造出的树中,一不小心就会出现环。这可怎么办呢,经过一晚上的深思熟虑,小码哥决定不出题了,摆烂!但是任务得完成呀。这时,小码哥突然有个主意,既然每次造树的数据都会出现环。如果在出现环的时候,就会立即停止造数据。在出现环之前,保证数据是符合要求的(即是一棵树)。你能帮小码哥找出这个环吗。按环上的顶点从大到小的顺序输出。 + +### 题目标签 +图论:图论基础 + +### 题目难度 +钻石 + +### 解析 +构建图,然后不断去掉出度为1的节点,这些节点肯定不是环中的节点,出掉这个节点有可能会导致出现新的出度为1的节点,要注意。然后将节点按序输出即可。 + +### Python 代码 +```python +def func(nodes,u): + node = nodes[u].pop() + nodes[node].remove(u) + if len(nodes[node]) == 1: + func(nodes,node) + +n,m = map(int,input().split()) +nodes = [[] for _ in range(n+1)] +for _ in range(m): + u,v = map(int,input().split()) + nodes[u].append(v) + nodes[v].append(u) + +for i in range(1,n+1): + if len(nodes[i]) == 1: + func(nodes,i) + +print(*[i for i in range(n,0,-1) if nodes[i] != []]) +``` + +## MC0349 - 区间数据处理(未完成) + +## MC0350 - 小码哥请吃饭 + +### 题目链接 +码蹄集OJ-小码哥请吃饭 + +### 问题描述 +小码哥组织了 n 个朋友一起做游戏。 +每个朋友都从一个装满了 n 个球的箱子摸一个球出来,球上写有不同的数字。 + +接着小码哥说拿到第 m 大的球的人我就请他吃饭,你知道第 m 大的球上的数字是多少吗? + +### 题目标签 +语言基础:数组 + +### 题目难度 +白银 + +### Python 代码 +```python +n,m = map(int,input().split()) +nums = [int(input()) for _ in range(n)] +nums.sort(reverse=True) +print(nums[m-1]) +``` + +## MC0351 - 区间询问和 + +### 题目链接 +码蹄集OJ-区间询问和 + +### 问题描述 +有n个数字,为a[1]…a[n]。 + +再来q个询问, 每个询问包含两个数字l,r,表示询问∑i=lr{a[i]} + +小码哥可以重新排列给出的a数组,使这q组询问所得结果之和最大,输出这个最大值。 + +### 题目标签 +算法基础:贪心 + +### 题目难度 +黄金 + +### 解析 +对于这道题,我们想让最大的数字被查询的次数最多,第二大的数字被查询的次数第二多... + +我们可以先使用前缀和,计算每个位置被查询了几次,然后排序,然后把数字也排序,让越大的数字显示的次数越多即可。 + +### Python 代码 +```python +n,q = map(int,input().split()) +nums = list(map(int,input().split())) +count = [0] * n +for _ in range(q): + r,l = map(int,input().split()) + count[r-1] += 1 + if l != n: + count[l] -= 1 +for i in range(1,n): + count[i] += count[i-1] +count.sort() +nums.sort() +ans = 0 +for i in range(n): + ans += count[i] * nums[i] +print(ans) +``` + +## MC0352 - 破解宝物封印(未完成) + +## MC0353 - 数字拆分 + +### 题目链接 +码蹄集OJ-数字拆分 + +### 问题描述 +小码哥在对数字的研究过程中发现,任何一个大于1的数字都能拆成很多组 a=b+c 的形式,也就是拆成两数之和,其中 b 和 c 都是正整数,现在给定一个整数 n ,请找出他的所有拆分方案。 + +注意10=2+8和10=8+2是同一个方案。 + +### 题目标签 +语言基础:循环结构 + +### 题目难度 +白银 + +### Python 代码 +```python +n = int(input()) +for i in range(n//2+1): + print(f"{n}={i}+{n-i}") +``` + +## MC0354 - 数字游戏(未完成) + +## MC0355 - 开篇签到 + +### 题目链接 +码蹄集OJ-开篇签到 + +### 问题描述 +(废话文学,轻吐槽,大家放松下紧张心情~) + +在计算机科学和编程领域,数组是最基本的数据结构之一。它由一系列按顺序排列的元素组成,这些元素可以是数字、字符或其他任何类型的数据。数组在存储和访问数据方面非常高效,因此在算法设计中扮演着重要的角色。 + +想象一下,你是一个数据分析师,手中有一个包含大量数据点的数组。你的任务是从这些数据点中找出一个特定的统计量:严格次小值。这个值在数据分析中非常重要,因为它可以帮助我们理解数据的分布情况,尤其是在我们需要确定数据的第二低点,而又不想将重复的数据点计算多次时。 + +为了更具体地描述这个问题,让我们来看一个例子。假设我们有一个数组:[3, 1, 4, 1, 5, 9]。这个数组的严格次小值是3,因为它是除了最小值1之外的最小值,并且它在数组中只出现了一次。 + +现在,让我们将这个问题形式化。给定一个长度为nn的数组a1,a2,…,an,其中每个元素都是整数,并且数组中的所有元素不全相同,你的目标是编写一个程序,它可以找到并输出这个数组的严格次小值。 + +为了完成这个任务,你可能需要考虑以下步骤: +1.遍历数组,找到数组中的最小值。 +2.再次遍历数组,找到第一个不等于最小值的元素,这个元素就是严格次小值。 + +请注意,本题数据保证数组中的元素是不全相同的,这意味着数组中至少有两个不同的元素。如果数组中有两个或更多相同的元素,并且这些元素是最小的,那么你的程序应该找到第二小的不同元素作为严格次小值。 + +现在,让我们开始编写代码来解决这个问题吧! + +### 题目标签 +语言基础:数组 + +### 题目难度 +白银 + +### Python 代码 +```python +n = int(input()) +nums = list(map(int,input().split())) +nums = list(set(nums)) +nums.sort() +print(nums[1]) +``` + +## MC0356 - 翻转反转翻转 + +### 题目链接 +码蹄集OJ-翻转反转翻转 + +### 问题描述 +给定字符串ss,f(s)表示该字符串全为1的最长前缀的长度与全为1的最长后缀的长度的较大值。例如:f(111001)=3,f(10011)=2。 + +现规定,两个字符串可以进行直接拼接也可以进行翻转拼接。例如有两个字符串s1=​1011,s2=0101,将s1 and s2拼接成一个新的字符串s,s可以是: + +10110101(将s1 and s2直接进行拼接),此时f(S)=1; +11010101(将s1翻过来与s2进行拼接),此时f(S)=2; +10111010(将s1与翻过来的s2进行拼接),此时f(S)=1; +11011010(将s1翻过来与翻过来的s2进行拼接)f(S)=2。 + +也可以让s2s2拼接在s1s1的前面,拼接规则同上。 + +现在,给你nn个仅包含0或1的字符串s1,s2,…,sn​。他们可以互相之间不断地拼接合并,最终形成一个总的字符串SS,问最大的f(SS)是多少? + +### 题目标签 +字符串:字符串基础 + +### 题目难度 +黄金 + +### 解析 +计算上全是 1 的字符串,找到左右连续的 1 最多的字符串即可 + +### Python 代码 +```python +def func(string:str) -> int: + cnt = 0 + while cnt < len(string) and string[cnt] == "1": + cnt += 1 + return cnt + +n = int(input()) +ans = 0 +max_prefix_num = 0 +for _ in range(n): + string = input() + prefix_num = max(func(string),func(string[::-1])) + if prefix_num == len(string): + ans += prefix_num + else: + max_prefix_num = max(max_prefix_num,prefix_num) +ans += max_prefix_num +print(ans) +``` + +## MC0357 - 移动移动移动(未完成) + +## MC0358 请相信我会做图论(未完成) + +## MC0359 我会等差数列(未完成) + +## MC0360 我会修改图(未完成) + +## MC0361 团队能量(未完成) + +## MC0362 异或(未完成) + +## MC0363 - 魔法占卜 + +### 题目链接 +码蹄集OJ-魔法占卜 + +### 问题描述 +众所周知(并不),小码妹是一名魔法少女。今天,她想要用魔法水晶球进行占卜,来决定今天是否是幸运日,如果是幸运日,她就会去城里的魔法商店探索,有很大可能能够买到稀有的魔法道具;否则,她就只能在家躺着追番咯。 + +占卜过程很简单,魔法水晶球将给出一个字符串S,作为今天的运势分析,同时,小码妹也会在羊皮纸上写下一个字符串T,如果可以通过删除S中的一些字符,使其与T相等,则可以认为占卜结果是幸运的,否则是不幸运的。 + +由于S和T都很长,小码妹又很懒,你能帮助她决定今天的行动吗? + +### 题目标签 +语言基础:字符串 + +### 题目难度 +白银 + +### Python 代码 +```python +S = input() +T = input() +i,j = 0,0 +sl,tl = len(S),len(T) +while i < sl and j != tl - 1: + if S[i] == T[j]: + j += 1 + i += 1 +if j == tl - 1: + print("Lucky!") +else: + print("QAQ Unlucky!") +``` + +## MC0364 - 魔法链路(未完成) + +### 题目链接 + +### 题目标签 + +### 题目难度 + +## MC0365 - 魔法链路2(未完成) + +### 题目链接 + +### 题目标签 + +### 题目难度 + +## MC0366 - 魔法天平(未完成) + +### 题目链接 + +### 题目标签 + +### 题目难度 + +## MC0367 - 魔法合并(未完成) + +### 题目链接 + +### 题目标签 + +### 题目难度 + +## MC0368 - 魔法合并2(未完成) + +### 题目链接 + +### 题目标签 + +### 题目难度 + +## MC0369 - 魔法徽章(未完成) + +### 题目链接 + +### 题目标签 + +### 题目难度 + +## MC0370 - 魔法修路(未完成) + +### 题目链接 + +### 题目标签 + +### 题目难度 + +## MC0371 - 魔法编程(未完成) + +### 题目链接 + +### 题目标签 + +### 题目难度 + +## MC0372 - 魔法咒语(未完成) + +### 题目链接 + +### 题目标签 + +### 题目难度 + +## MC0373 - 魔法少女小码妹外传之与小码哥的决斗(未完成) + +### 题目链接 + +### 题目标签 + +### 题目难度 \ No newline at end of file diff --git a/docs/blog/technology/bitwise-subsequences.md b/docs/blog/technology/bitwise-subsequences.md new file mode 100644 index 0000000..ecefe14 --- /dev/null +++ b/docs/blog/technology/bitwise-subsequences.md @@ -0,0 +1,85 @@ +--- +title: 通过位运算快速生成所有的子序列 +createTime: 2026/01/09 16:15:00 +cover: /images/elysia/10.jpg +coverStyle: + layout: right +permalink: /archives/ea20bdda-0d49-4472-a647-2e305a930d11/ +--- +## 一、子序列的本质 + +子序列是从原字符串中选择任意数量的字符(可以是 0 个、1 个、...、所有字符),且保持这些字符的原始顺序形成的字符串。 + +例如:原字符串 `"abc"` 的子序列包括 `"a"`, `"b"`, `"c"`, `"ab"`, `"ac"`, `"bc"`, `"abc"` 和空字符串 `""`(共 $2^3 = 8$ 种可能性)。 + +## 二、位掩码(Bitmask)的引入 + +假设字符串长度为 `n`,我们可以用一个 `n` 位的二进制数来表示是否选择某个字符: +- 二进制数的每一位对应原字符串的一个字符。 +- 如果某一位是 `1`,表示选择对应的字符;如果是 `0`,表示不选择。 + +例如,对于字符串 `"abc"`(`n=3`): + +| 二进制数 | 十进制 | 选择情况 | 生成子序列 | +| :--- | :--- | :--- | :--- | +| `101` | 5 | 选择第 1 个字符 "a" 和第 3 个字符 "c" | `"ac"` | +| `010` | 2 | 选择第 2 个字符 "b" | `"b"` | + +## 三、遍历所有可能的二进制数 + +所有可能的二进制数范围是 `0`(全 0)到 $2^n - 1$(全 1)。例如,`n=3` 时: +- 范围是 `000` (0) 到 `111` (7),共 $2^3 = 8$ 种可能。 +- 每个二进制数对应一种子序列选择方式。 +- 如果包含 `000` (0),对应空字符串 `""`。若不需要空字符串,可以从 `1` 开始遍历。 + +## 四、如何将二进制数转换为子序列? + +### 1. 外层循环:遍历所有可能的二进制数 +对于 `n=3`,遍历 `1` (`001`) 到 `7` (`111`)。 + +### 2. 内层循环:检查每一位是否为 1 +- 对于每个二进制数 `mask`,遍历其每一位 `i`(从 `0` 到 `n-1`)。 +- 如果 `mask` 的第 `i` 位是 `1`(即 `mask & (1 << i)` 为真),则将原字符串的第 `i` 个字符加入子序列。 + +## 五、代码示例 + +```python +def get_all_subsequences(s): + n = len(s) + subsequences = [] + # 遍历 1 到 2^n - 1 (排除空字符串) + for mask in range(1, 1 << n): + subseq = [] + for i in range(n): + # 检查 mask 的第 i 位是否为 1 + if mask & (1 << i): + subseq.append(s[i]) + subsequences.append(''.join(subseq)) + return subsequences + +# 测试 +print(get_all_subsequences("abc")) +# 输出: ['a', 'b', 'ab', 'c', 'ac', 'bc', 'abc'] +``` + +## 六、应用场景 + +在处理类似 **X 质数** 的问题时,我们需要检查一个数字的所有数字子序列。通过这种位运算的方式,可以非常高效地生成所有组合并进行判断。 + +```python +def solve_x_prime(num): + s = str(num) + n = len(s) + for mask in range(1, 1 << n): + subseq_str = "" + for i in range(n): + if mask & (1 << i): + subseq_str += s[i] + + # 将生成的子序列转换为整数并判断是否为质数 + p = int(subseq_str) + if is_prime(p): + return True + return False +``` +