蓝桥备赛——贪心(2)

本文讲述了作者在蓝桥杯备赛中遇到的一道贪心算法题目,通过对比自己的代码和AC代码,发现了代码优化的方法。AC代码利用异或运算简化了问题,而作者最初的思路是通过判断相邻元素是否相同来决定翻转次数。经过调整,作者的代码也实现了正确解答。文章强调了学习他人简洁代码的重要性。
摘要由CSDN通过智能技术生成

题干 

我的代码

dic={'*':1,'o':0}
s1=input()
s2=input()
s1=list(s1)
s2=list(s2)
num1=''
num2=''
for i in s1:
    # print(i)
    num1=num1+str(dic[i])
for j in s2:
    num2+=str(dic[j])
# print(num1)
# print(num2)

num1=list(num1)
num2=list(num2)

count=0
for i in range(len(num1)-1):
    if num1[i]!=num2[i] and num1[i+1]!=num2[i+1]:
        # print(num1[i],num1[i+1])
        count+=1
        num1[i]=num2[i]
        num1[i+1]=num2[i+1]
        # print(num1[i],num1[i+1])
set1=0
set2=0
roun=0
for j in range(len(num1)):
    if num1[j]!=num2[j] :
        roun += 1
        if roun%2==1:
            set1=j
        if roun%2==0:
            set1=j-set1
            count+=set1
            set1=0
print(count)

与下面的AC代码相比,我的代码冗余内容非常多,并且还没有通过全部样例,只能通过66.6%的样例。我考虑的角度是分成两种情况,假如连续两个地方不同,则只需要一次翻转即可,反之就是两个作差(因为每次转换都是相邻两个元素进行翻转变换,那么也就类似于是一种传递运算。)此外,我为了方便运算,在开头将*o字符串都替换成了0、1,但是最后貌似没起啥作用,结合下面的AC代码可以看出使用异或运算可以很好地简化代码量。

AC Code 

import os
import sys

# 请在此输入您的代码
d1 = [1 if c == "*" else 0 for c in input()]  # 将字符串转换为0,1数组
d2 = [1 if c == "*" else 0 for c in input()]
ans = 0
for i in range(len(d1) - 1):  # 遍历列表,最后一个元素无需遍历
    if d1[i] != d2[i]:  # 若当前元素不相等翻转当前元素和后一个元素
        d1[i] ^= 1  # 对当前元素和1进行位运算异或完成翻转
        d1[i + 1] ^= 1  # 后一个元素同理
        ans += 1  # 翻转次数加一
print(ans)

经过对比发现,AC代码没有考虑相邻两种都不同的情况。于是我把我代码中考虑的第一种情况注释掉了,发现我的代码也AC了,我的代码如下:

dic={'*':1,'o':0}
s1=input()
s2=input()
s1=list(s1)
s2=list(s2)
num1=''
num2=''
for i in s1:
    # print(i)
    num1=num1+str(dic[i])
for j in s2:
    num2+=str(dic[j])
# print(num1)
# print(num2)

num1=list(num1)
num2=list(num2)

count=0
# for i in range(len(num1)-1):
#     if num1[i]!=num2[i] and num1[i+1]!=num2[i+1]:
#         # print(num1[i],num1[i+1])
#         count+=1
#         num1[i]=num2[i]
#         num1[i+1]=num2[i+1]
#         # print(num1[i],num1[i+1])
set1=0
set2=0
roun=0
for j in range(len(num1)):
    if num1[j]!=num2[j] :
        roun += 1
        if roun%2==1:
            set1=j
        if roun%2==0:
            set1=j-set1
            count+=set1
            set1=0
print(count)

 不过,结合别人的AC代码,还有很多需要借鉴的地方,比如

d1 = [1 if c == "*" else 0 for c in input()]  # 将字符串转换为0,1数组
d2 = [1 if c == "*" else 0 for c in input()]

这一段代码,使用列表表达式,对原字符串进行字母替换为0、1序列。

d1[i] ^= 1  # 对当前元素和1进行位运算异或完成翻转
d1[i + 1] ^= 1  # 后一个元素同理

再者,像上面这个代码,对1做位运算,就可以达到取反的效果。

再来点更直观的

a=0
print(a^1)
print(a^1^1)

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

牛哥带你学代码

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

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

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

打赏作者

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

抵扣说明:

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

余额充值