每日一算法(20)

每日算法篇-蓝桥练习篇

“我好害怕独处,可我没什么身份去找她,可我也不想找别人,之前独处就是焦虑,我觉得还好就是焦虑他能被繁忙遗忘,现在是痛苦,总有一个声音一直在告诉我,你不开心,确实找不到快乐的多巴胺,每天都很丧,希望好过来,但又不希望,可以的话,别让我一个人独处,给我安排一堆事,让我忙起来吧,谢谢啦。前两年的双十一都是你陪我度过,今年希望你别给我太多狗粮,要不还是删了我吧。”——努力成为程序员的耿耿(2021/11/11)

题目————完美的代价

问题描述
  回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
  交换的定义是:交换两个相邻的字符
  例如mamad
  第一次交换 ad : mamda
  第二次交换 md : madma
  第三次交换 ma : madam (回文!完美!)
输入格式
  第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
  第二行是一个字符串,长度为N.只包含小写字母
输出格式
  如果可能,输出最少的交换次数。
  否则输出Impossible
样例输入
5
mamad
样例输出
3

思考: 要根据字符长度,以及各个字符出现频次进行判别
1.n为偶数
里面含有的字母有一个及其以上是奇数个——一定不能回产生回文
里面含有的字母全是偶数个——可以,只用计算次数就好
2.n为奇数
里面含有的字母有一个是奇数个——可以,只用计算次数就好
里面含有的字母有多个是奇数个——一定不能回产生回文
里面含有的字母全是偶数个——一定不能产生回文

n = int(input())
pal = list(input())#就不要用字符串接收了,字符串不好交换位置
count = flag = 0  # count用来计数,flag判断是否有一个字母出现基数次了
m = n - 1
for i in range(m):  # 从头遍历到倒数第二个字符
    for k in range(m, i - 1, -1):  # 从后往前找
        if k == i:  # 如果找不到相同的
            if n % 2 == 0 or flag == 1:   #判断是基数还是偶数,以及出现的次序
                print('Impossible')
                exit()
            flag = 1  
            count += int(n / 2) - i   #这是已经确认是字母出现奇数次,而且总共字母也是奇数需要把这个挪到中间
        elif pal[k] == pal[i]:
            for j in range(k, m):  # 找到相同的,进行交换
                pal[j], pal[j + 1] = pal[j + 1], pal[j]
                count += 1  # 计数器加1
            m -= 1  # 拍过次序的就不要比较了
            break
print(count)

昨天其实写好了,但是忘发布了,就在草稿里,但是还算是昨天的吧哈哈哈,下次睡前我会多看一眼的。

你可能感兴趣的:(数据结构,算法,python)