题目:
小蓝最近迷上了全排列, 现在他有一个长度为 17 的排列, 里面包含的元素 有: abcdefghijklnopqr, 即 a 至 rr 中除了 mm 以外的所有小写字母, 这 17 个字母在任何一个排列中都恰好出现一次。前面几个排列依次是:
第 1 个排列为: abcdefghijklnopqr;
第 2 个排列为: abcdefghijklnoprq;
第 3 个排列为: abcdefghijklnoqpr;
第 4 个排列为: abcdefghijklnogrp;
第 5 个排列为: abcdefghijklnorpq;
第 6 个排列为: abcdefghijklnorqp;
第 7 个排列为: abcdefghijklnpoqr;
第 8 个排列为: abcdefghijklnporq;
第 9 个排列为: abcdefghijklnpqor;
第 10 个排列为: abcdefghijklnpqro。
对于一个排列, 有两种转移操作:
-
转移到其下一个排列。如果当前排列已经是最后一个排列, 那么下一个 排列就是第一个排列。
-
转移到其上一个排列。如果当前排列是第一个排列, 那么上一个排列就 是最后一个排列。
小蓝现在有两个排列, 分别为排列 A:A: aejcldbhpiogfqnkr, 以及排列 BB : ncfjboqiealhkrpgd, 他现在想知道, 在只有上述两种转移操作的前提 下, 排列 AA 最少转移多少次能得到排列 BB 。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数, 在提交答案时只填写这个整数, 填写多余的内容将无法得分。
运行限制
- 最大运行时间:1s
- 最大运行内存: 512M
难点:
自己走了一遍包括看了并理解了题解,其实难点就是长度为17的字符串一共有多少总排列,和如何确定这个排列是第几个排列
题解中很好的解决了这个问题,但没有过多的解释,下面是一些关于我的理解和注释后的代码,应该好好思考之后是可以理解的。
代码(python):
import os
import sys
# 请在此输入您的代码
# mp用于存储第一个排列中每一个字母对应的位置,用字典的方式
mp = {}
s1 = "aejcldbhpiogfqnkr"
s2 = "ncfjboqiealhkrpgd"
arr = [0]*20
arr[0] = 1
# 初始化arr,arr[i]用于存储长度为i字符串最多有多少种排列,算是一个规律
for i in range(1,18):
arr[i] = arr[i-1]*i
# 获取s这个字符串是第几个排列
def work(s):
ans = 0
n = len(s)
for i in range(n):
# 获取这个字母的位置,赋值给val
val = mp[s[i]]
# 哇趣,很聪明的方法计算第几个排列,一个字母一个字母来看
# 找到这个字母往前移的位置,字母后面则表示已经进行了几次全排列
# 如果在原本位置上的话,即与第一个排列一样,则val会减到0,既不用加上ans
for j in range(i):
if s[j] < s[i]:
val-=1
ans = ans + val * arr[n-1-i]
return ans
# 因为缺少字母m,所以不能直接用码来获取位置,初始化mp字典
cnt = 1
for ch in "abcdefghijklnopqr":
mp[ch] = cnt
cnt+=1
a1 = work(s1)
a2 = work(s2)
# 正过来和反过来中较小的那一个
ans = min(a2-a1, arr[17]-a2+a1)
print(ans)