蓝桥杯-练习题目(21-40)

21.题目21:

回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
  交换的定义是:交换两个相邻的字符
  例如mamad
  第一次交换 ad : mamda
  第二次交换 md : madma
  第三次交换 ma : madam (回文!完美!)
输入格式
  第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
  第二行是一个字符串,长度为N.只包含小写字母
输出格式
  如果可能,输出最少的交换次数。
  否则输出Impossible
'''
①判断:
若字符串长度为偶数,则每个字符出现的次数都必须是偶数次,否则不对称
若字符串长度为奇数,则只能有一个字符出现奇数次(在字符串最中间出现一次)
判断实现比较简单,注意减少代码复杂度(题给字符串长度范围是8000,python很容易运行超时)
②贪心策略:
对于偶数长度的字符串,我们从第一个开始遍历,再倒序遍历出同样的,这个倒序遍历出来的序号,就是该移动的步数。 倒序列表需要不断更新,已经构成回文的外层字符不再考虑。
对于奇数的字符串,其实贪心策略和偶数的时候一样,只不过我们一直遍历下去会有一个字符没有匹配,那么这个字符肯定是放在中间的,我们设置一个判断,假如剩余的该字符个数不是1,
按照和偶数一样的遍历,如果该字符是1,直接移动到最中间的位置。

#原文地址:https://blog.csdn.net/hallohalloha/article/details/113332805?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-2&spm=1001.2101.3001.4242
#https://blog.csdn.net/qq_45894553/article/details/104611483
'''
n = int(input())
S = list(input())

count = 0 # 用于计算交换的次数
i = 0 #用于计数外层丢弃的字符串(单侧),用来显示当前判断字符串(从前往后数)的位置
flag = 0 #用来判断是否已经有了一个单独的奇数个字符串

while len(S)>1:
    for k in range(len(S)-1,0,-1):
        if S[k] == S[0]:
            count += len(S) - 1 - k
            S.pop(0) #将开始元素pop出去,其将会导致列表的索引整体向前移动1
            i += 1
            S.pop(k - 1)
            break #找下一个
        
        elif k == 1: #没找到相同的(孤独的),移动到中间
            S.pop(0) # 单个的话,直接扔掉没事的
            # impossible的两种情况:
            # ①偶数个字符,却存在一个字符出现奇数次
            # ②奇数个字符,但已经有一个字符只出现奇数次了,不能再出现下一个
            if n%2 == 0 or flag == 1:#对于flag只能一次被赋值为1,这块再来第二次的话就不是回文数了
                print("Impossible")
                exit()# 使得程序正常退出
            flag = 1
            count += n//2 - i #原来字符串一半减去之前丢弃掉的单侧字符串
print(count)
完美的代价

 22. 题目22(这个我找的代码和我的都有些瑕疵,但是系统可以100通过,希望会的大佬可以帮下小弟):

Tom教授正在给研究生讲授一门关于基因的课程,有一件事情让他颇为头疼:一条染色体上有成千上万个碱基对,它们从0开始编号,到几百万,几千万,甚至上亿。
  比如说,在对学生讲解第1234567009号位置上的碱基时,光看着数字是很难准确的念出来的。
  所以,他迫切地需要一个系统,然后当他输入12 3456 7009时,会给出相应的念法:
  十二亿三千四百五十六万七千零九
  用汉语拼音表示为
  shi er yi san qian si bai wu shi liu wan qi qian ling jiu
  这样他只需要照着念就可以了。
  你的任务是帮他设计这样一个系统:给定一个阿拉伯数字串,你帮他按照中文读写的规范转为汉语拼音字串,相邻的两个音节用一个空格符格开。
  注意必须严格按照规范,比如说“10010”读作“yi wan ling yi shi”而不是“yi wan ling shi”,“100000”读作“shi wan”而不是“yi shi wan”,“2000”读作“er qian”而不是“liang qian”。

#原文地址:https://blog.csdn.net/qq_42212961/article/details/103687709

#1.初始化及变量
num = list(map(int, input()))
wei = {1:'shi', 2:'bai', 3:'qian', 4:'wan',5:'shi', 6:'bai', 7:'qian', 8:'yi', 9:'shi'}
yin = {1:'yi', 2:'er', 3:'san', 4:'si', 5:'wu', 6:'liu', 7:'qi', 8:'ba', 9:'jiu'}
qu = {1:'wan',2:'yi'}
all_yin = []

'''
1234:
1 在 yin里边,读作'yi',all_yin加'yi';
len(num)-1-i = 4-1-0 = 3(对应于qian) # len(num)-1是因为没有个位
'''

def elseWei(j):
    if num[j:] == ['0']*(len(num)-1-j):
        return True
    else:
        return False
        
def fayin(num):
    for i in range(len(num)):
        #1.特殊的0的发言处理:
        if num[i] == 0 and i < len(num) - 1: #123005,底下有个i+1会出范围
            if num[i+1] != 0 and (len(num)-1-i == 9 or len(num) - 1 - i == 5):
                all_yin.append('ling')
            if len(num)//4 != 0 and elseWei(i):
                all_yin.append(qu[len(num)//4])
                continue
            continue #结束本次循环
        #2.高位的10

        #主体部分
        if num[i] in yin: #判断key是否在yin里边
            all_yin.append(yin[num[i]])
        if len(num)-1-i in wei:
            all_yin.append(wei[len(num)-1-i])
            
    return all_yin

all_yin = fayin(num)
print(' '.join(all_yin)) #这个还是挺好用的
            
读数字

 23.题目23

最近FJ为他的奶牛们开设了数学分析课,FJ知道若要学好这门课,必须有一个好的三角函数基本功。所以他准备和奶牛们做一个“Sine之舞”的游戏,寓教于乐,提高奶牛们的计算能力。
  不妨设
  An=sin(1–sin(2+sin(3–sin(4+...sin(n))...)
  Sn=(...(A1+n)A2+n-1)A3+...+2)An+1
  FJ想让奶牛们计算Sn的值,请你帮助FJ打印出Sn的完整表达式,以方便奶牛们做题。

仅有一个数:N<201。

请输出相应的表达式Sn,以一个换行符结束。输出中不得含有多余的空格或换行、回车符。

#Sine之舞
#本代码并不是本人原创;
#源码地址:https://www.cnblogs.com/fate-/p/12294459.html
def An(n,s):
    for i in range(1,n+1):
        s = s + "sin({}".format(i)
        if i != n:
            if i%2 == 1:
                s = s + "-"
            else:
                s = s + "+"
        else:
            s = s + ")"*n
    return s

def sn(n,s):
    s = s + "("*(n-1)
    for i in range(1,n+1):
        s = An(i,s)
        s = s + "+{}".format(n-i+1)
        if i != n:
            s = s + ")"
    return s

def main():
    n = int(input())
    s = ''
    s = sn(n,s)
    print(s)

if __name__ == '__main__':
    main()

'''
an就先输出一个sin(+数字

如果数字没到n的话,数字是奇数就加减号,偶数就加加号

到n的话,输出n个括号

sn要先输出n-1个括号

然后调用an

然后+数字

数字是从n到1

数字没到1·的话,就接括号

到1的话,就啥也不接。
'''
    
Sine之舞

24.题目24

FJ在沙盘上写了这样一些字符串:
  A1 = “A”
  A2 = “ABA”
  A3 = “ABACABA”
  A4 = “ABACABADABACABA”
  … …
  你能找出其中的规律并写所有的数列AN吗?

输入格式
  仅有一个数:N ≤ 26。
输出格式
  请输出相应的字符串AN,以一个换行符结束。输出中不得含有多余的空格或换行、回车符。
def FJ(N,letters,S):
    AN = [] #用来存储每次的An
    AN.append(S)
    for i in range(N):
        AN.append(AN[i] + letters[i+1] + AN[i])
    return AN
        
def main():
    #1.产生所有字母
    N = int(input()) #An的N
    letters = '' #存储所有的字母
    for i in range(26):
        letters += chr(ord("A") + i)
    S =  'A'#每次递归的字符串

    #2.FJ,返回来一个列表
    AN = FJ(N,letters,S)

    #3.格式化输出
    result = list(AN[-2]) #因为有个'A'
    print("".join(result))

if __name__ == "__main__":
    main()
    
FJ的字符串

25.题目25(这个看测评的输入,输出都是正确的,不知道为什么不对)

问题描述
  有n(2≤n≤20)块芯片,有好有坏,已知好芯片比坏芯片多。
  每个芯片都能用来测试其他芯片。用好芯片测试其他芯片时,能正确给出被测试芯片是好还是坏。而用坏芯片测试其他芯片时,会随机给出好或是坏的测试结果(即此结果与被测试芯片实际的好坏无关)。
  给出所有芯片的测试结果,问哪些芯片是好芯片。
输入格式
  输入数据第一行为一个整数n,表示芯片个数。
  第二行到第n+1行为n*n的一张表,每行n个数据。表中的每个数据为0或1,在这n行中的第i行第j列(1≤i, j≤n)的数据表示用第i块芯片测试第j块芯片时得到的测试结果,1表示好,0表示坏,i=j时一律为1(并不表示该芯片对本身的测试结果。芯片不能对本身进行测试)。
输出格式
  按从小到大的顺序输出所有好芯片的编号
#解析:题目中已知好的芯片比坏的芯片多,而且用每个芯片都测试其他的芯片,
#所有对于一个芯片来说,当测试结果为好的次数大于测试结果为坏的次数时,他就是好的芯片。
import numpy as np

#1.输入存储
n = int(input()) #芯片的个数
a = np.zeros((n,n))
i = 0

while i<n:
    a[i] = list(map(int,input().split()))
    i = i + 1

#2.判断
sum1 = np.sum(a,axis = 0) #0竖着,1横着
result = []#存储每片芯片的判断结果
for i in range(n):
    if n%2 == 1:
        if sum1[i] > n//2: #奇数,因为有个1是自己判断自己的
            result.append(1)
        else:
            result.append(0)
    else:
        if sum1[i] >= n//2: #因为有个1是自己判断自己的
            result.append(1)
        else:
            result.append(0)

#3.输出
result1 = [str(i+1) for i in range(n) if result[i] != 0] #[表达式 for 迭代变量 in 可迭代对象 [if 条件表达式] ]
print(" ".join(result1)) #join期待的是一个存放字符串的列表
芯片测试
原文地址:https://www.cnblogs.com/xiao-yu-/p/14377534.html