【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 = 0
for 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 += 1
print(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++ 2s 256M C 2s 256M Java 3s 256M Python3 4s 256M PyPy3 4s 256M Go 4s 256M JavaScript 4s 256M
思路与算法
思路
贪心算法的核心思想是局部最优选择,即每一步都选择当前看起来最优的操作,最终达到全局最优解。在这个问题中,贪心策略的关键在于:
预处理数组:先对数组进行排序和去重,得到一个严格递增的数组。
遍历去重后的数组:对于每个元素,检查它与后续两个元素是否能构成连续递增的三元组。如果可以,则计数加 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 = 1
while y < n:
if arr[y] != arr[x-1]:
arr[x] = arr[y]
x += 1
y += 1
res = 0
for i in range(x-2):
num = arr[i]
if arr[i+1] == num+1 and arr[i+2] == num+2:
res += 1
print(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++ 2s 256M C 2s 256M Java 3s 256M Python3 4s 256M PyPy3 4s 256M Go 4s 256M JavaScript 4s 256M
思路与算法
思路
贪心策略的核心是局部最优决策:遍历字符串时,一旦遇到元音字母,立即用括号将其包裹,并确保相邻元音字母被分隔。
算法步骤
初始化:结果字符串 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 = 0
for i in S:
if Judge(i):
count += 1
if count > 1:
res += ")("
count += 1
res += i
res += ")"
if count == 0:
print(S)
else:
print(res)
原文地址:https://blog.csdn.net/m0_73983707/article/details/148558760
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!
