当前位置: 首页 > news >正文

【Python 算法零基础 6.贪心算法】

你是我生命里不朽的月亮,予我清辉如霜

                                                        —— 25.6.10

一、算法描述

按照某种策略一步一步去选择,每次都是选择最优策略,不从整体最优考虑


二、实战练习

1.翻硬币

题目描述

小明正在玩一个"翻硬币"的游戏。

桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。

比如,可能情形是:**oo***oooo;

如果同时翻转左边的两个硬币,则变为:oooo***oooo。

现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?

我们约定:把翻动相邻的两个硬币叫做一步操作。

输入描述

两行等长的字符串,分别表示初始状态和要达到的目标状态。

每行的长度<1000。

输出描述

一个整数,表示最小操作步数。

输入输出样例

示例

输入

**********
o****o****

输出

5

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 64M

思路与算法

思路

从左到右遍历字符串,一旦发现 a[i] 与 b[i] 不匹配,立即翻转 a[i] 和 a[i+1]这样可以保证每次操作都能解决当前位置的不匹配问题,而不会影响已经处理过的部分。

算法步骤

初始化读取输入的字符串 a 和目标字符串 b,并初始化操作次数 res = 0

遍历字符串从左到右遍历字符串 a 的每个字符。

检查不匹配对于每个位置 i,如果 a[i] != b[i],则执行以下操作:

        翻转 a[i] 和 a[i+1](将 'o' 变为 '','' 变为 'o')。

        操作次数 res 加 1。

终止条件遍历结束后,res 即为将 a 转换为 b 所需的最小操作次数。

import os
import sys# 请在此输入您的代码
a = input()
b = input()n = len(a)
a = [i for i in a]
res = 0for i in range(n):if a[i] != b[i]:a[i] = '*' if a[i] == 'o' else 'o'a[i+1] = '*' if a[i+1] == 'o' else 'o'res += 1print(res)


2.1键3连

问题描述

给定一个长度为 n 的整数数列 A,A 中第 i 个元素为 Ai​(1≤i≤n),整数 res 初始为 0,如果一个数 a 存在于 A 且 a+1,a+2 均存在于 A 中,则 res 加 1,请输出最后 res 的值。

输入格式

输入共 2 行。

第一行包含一个整数 n,表示整数数列 A 中元素的个数。

第二行包含 n 个整数,表示整数数列 A 中各元素的值。

输出格式

输出共一行,包含一个整数,表示最后 res 的值。

样例输入

5
1 2 2 3 4

样例输出

2

评测数据规模

对于所有评测数据,3≤n≤10^5,1≤A_i​≤10^5。

运行限制

语言最大运行时间最大运行内存
C++2s256M
C2s256M
Java3s256M
Python34s256M
PyPy34s256M
Go4s256M
JavaScript4s256M

思路与算法 

思路

贪心算法的核心思想是局部最优选择,即每一步都选择当前看起来最优的操作,最终达到全局最优解。在这个问题中,贪心策略的关键在于:

        预处理数组先对数组进行排序和去重,得到一个严格递增的数组。

        遍历去重后的数组对于每个元素,检查它与后续两个元素是否能构成连续递增的三元组。如果可以,则计数加 1,并继续检查后续元素。

算法步骤

输入处理与排序读取数组长度 n 和数组 arr。对数组进行排序,以便后续处理。

原地去重使用双指针法原地去重,将不重复的元素移到数组前部。指针 x 记录当前不重复元素的末尾位置,指针 y 遍历原数组。

统计连续三元组遍历去重后的数组,检查每个元素 arr[i] 是否满足 arr[i+1] == arr[i]+1 且 arr[i+2] == arr[i]+2。如果满足条件,则计数 res 加 1。

import os
import sys# 请在此输入您的代码
n = int(input())
arr = list(map(int, input().split()))arr = sorted(arr)# x代表现在已经做完处理的非重复数据个数
# y代表当前正在处理的arr列表中的元素下标
x = 1
y = 1while y < n:if arr[y] != arr[x-1]:arr[x] = arr[y]x += 1y += 1res = 0
for i in range(x-2):num = arr[i]if arr[i+1] == num+1 and arr[i+2] == num+2:res += 1print(res)


3.分开元音字母

问题描述

给定一串长度为 n 且只含有小写英文字母的字符串 S,请你用小括号 '(' 与 ')' 将字符串 S 分开,使得每对小括号内有且仅有一个元音字母。如果有多种分开的方式,输出各个括号内的字母数组成的数组中字典序最大的那一个。

元音字母有 a,e,i,o,u。

例如:字符串 abe,可分为 (ab)(e),与(a)(be),前者括号内的字母数组成的数组为 2,1,后者为 1,2,所以答案为 (ab)(e)。

注意:如果给定的字符串中没有元音字母,则无需增加括号,直接输出字符串即可。

输入格式

输入共一行,包含一串字符串 S。

输出格式

输出共一行,包含一串字符串,表示被小括号分开后的字符串 S。

样例输入

abcdeeko

样例输出

(abcd)(e)(ek)(o)

评测数据规模

对于所有评测数据,1≤n≤10^5。

运行限制

语言最大运行时间最大运行内存
C++2s256M
C2s256M
Java3s256M
Python34s256M
PyPy34s256M
Go4s256M
JavaScript4s256M

思路与算法

思路

贪心策略的核心是局部最优决策:遍历字符串时,一旦遇到元音字母,立即用括号将其包裹,并确保相邻元音字母被分隔。

算法步骤

初始化结果字符串 res 初始化为 "("。计数器 count 初始化为 0,用于记录已处理的元音字母数量。

遍历字符串对于每个字符 i

        若为元音count 加 1。若当前不是第一个元音(即 count > 1),说明前面已有元音,需要分隔:在结果字符串中追加 ")(",表示前一个括号结束,新括号开始。将当前元音字符追加到结果字符串。

        若非元音直接追加到结果字符串。

收尾处理遍历结束后,在结果字符串末尾追加 ")",形成完整的括号结构。

特殊情况处理若整个字符串中没有元音(即 count == 0),直接输出原字符串。

import os
import sys# 请在此输入您的代码
S = input()
n = len(S)def Judge(s):return s in ['a', 'e', 'i', 'o', 'u']res = "("
count = 0for i in S:if Judge(i):count += 1    if count > 1:res += ")("count += 1res += i
res += ")"if count == 0:print(S)
else:print(res)

 

相关文章:

  • Linux基本指令(包含vim,用户,文件等方面)超详细
  • 小白理财 - 指数基金定投
  • Proof of Talk专访CertiK联创顾荣辉:全周期安全方案护航Web3生态
  • 【前端面试】八、工程化
  • RV1126+OPENCV在视频中添加LOGO图像
  • 在QT中使用OpenGL
  • 使用Apache POI操作Word文档:从入门到实战
  • 谷粒商城-分布式微服务 -集群部署篇[一]
  • 鹰盾视频加密器Windows播放器禁止虚拟机运行的技术实现解析
  • thinkphp ThinkPHP3.2.3完全开发手册
  • 品牌形象全面升级|Apache Fory:破界新生,开启高性能序列化新纪元
  • 十六、【ESP32开发全栈指南:I2C接口详解及BH1750传感器实战】
  • 04__C++特殊的函数语法
  • spring boot2 +java-jwt轻量实现jwt
  • 数据结构(9)排序
  • 成功在 Conda Python 2.7 环境中安装 Clipper(eCLIP peak caller)
  • 01.pycharm整合conda
  • 【数据结构】图论最短路圣器:Floyd算法如何用双矩阵征服负权图?
  • C# TextBox 控件限制输入字符为十六进制字符串
  • 什么是哈希函数
  • 帝国网站后台管理系统/专门做推广的软文
  • 黑客是如何攻击网站的/最新百度快速排名技术
  • 中山技术支持中山网站建设/南宁seo公司
  • 广元做网站/推介网
  • 五莲网站建设/深圳网络推广培训中心
  • 做养生类项目的网站/口碑营销的形式