数列还原-网易python

来源:互联网 发布:linux 虚拟机不能上网 编辑:程序博客网 时间:2024/06/03 19:41

题目描述
牛牛的作业薄上有一个长度为 n 的排列 A,这个排列包含了从1到n的n个数,但是因为一些原因,其中有一些位置(不超过 10 个)看不清了,但是牛牛记得这个数列顺序对的数量是 k,顺序对是指满足 i < j 且 A[i] < A[j] 的对数,请帮助牛牛计算出,符合这个要求的合法排列的数目。
输入描述:
每个输入包含一个测试用例。每个测试用例的第一行包含两个整数 n 和 k(1 <= n <= 100, 0 <= k <= 1000000000),接下来的 1 行,包含 n 个数字表示排列 A,其中等于0的项表示看不清的位置(不超过 10 个)。
输出描述:
输出一行表示合法的排列数目。
示例1
输入

5 5
4 0 0 2 0
输出

2

解析:

# 数列还原# 原理:参考实例[4,0,0,2,0]# 1)第一步,计算已知数子的对数sum1,即[4,2],0种;复杂度n^2# 第二步,前提,首先列举出所有的未知数字的排列组合,保存起来;# 以上的例子为:[(1, 3, 5), (1, 5, 3), (3, 1, 5), (3, 5, 1), (5, 1, 3), (5, 3, 1)]# 选取其中一个组合为例(1, 3, 5),分别将三个数中的一个插入原数组中[4,0,0,2,0]# 例如,第一次插入的是1,原数组变为[4,1,0,2,0]通过分别计算将1,与1左边的和右边的数字进行比较(即[4]和[2])# 2)计算出(1, 3, 5)相应的对数,然后进行累加的sum2# 判断sum1+sum2 == k?# itertools用于字符串/数字的全排列,itertools.permutations("abc",3),输出结果为abc, acb, bac, bca, cab和cba。# copy用于复制数组,python采用的是:如果参数可变就为引用传递,否则则是值传递。(列表list可变[],元组tuple不可变())import itertoolsimport copyn, k = map(int, input().split())array = list(map(int, input().split()))# 计算第一个值sum1firstNum = 0;for i in range(len(array)):    if array[i] != 0:        for j in range(i, len(array)):            if array[j] != 0 and array[i] < array[j]:                firstNum += 1# unknownNum存储未知的数字unknownNum = []tempArray = [0 for i in range(0, n + 1)]for i in array:    if i != 0:        tempArray[i] = 1for i in range(1,n + 1):    if tempArray[i] == 0:        unknownNum.append(i)# 计算每一个未知排列,所对应的数量sum2def calvalue(list, arr):    sum = 0    j = 0    for i in range(len(arr)):        if arr[i] == 0:            arr[i] = list[j]            j += 1            # 分别计算左右            for k in range(i):                if arr[k] != 0 and arr[k] < arr[i]:                    sum += 1            for k in range(i + 1, len(arr)):                if arr[k] != 0 and arr[k] > arr[i]:                    sum += 1    return sum# 存储所有的未知数的排列情况unknownArray = list(itertools.permutations(unknownNum, len(unknownNum)))result = 0for x in range(len(unknownArray)):    total = 0;    temp = unknownArray[x]    temp = list(temp)    # 由于传的是直接引用,数组array的值会改变,所以需要深度(完全复制,不共享内存)复制    temparr = copy.deepcopy(array)    total = calvalue(temp, temparr) + firstNum    if total == k:        result += 1print(result)# 全排列函数permutation,需要使用递归来列举,也是一个知识点(参考网络)# 除了使用模块,当然可以自己写一个函数来实现:# def permutation(xs):   #简化问题,假定形参xs是列表#     if len(xs) == 0 or len(xs) == 1:#         return [xs]#     result = []#     for i in xs:#         temp_list = xs[:] #对xs进行切片操作,使得temp_list的值和xs一样 但是temp_list的改变不影响xs#         temp_list.remove(i)#         temp = permutation(temp_list) #使用递归 生成删掉一个元素的xs的全排列#         for j in temp:   #对temp中的每一项再进行遍历#             j[0:0] = [i]   #在index 0 的位置插入之前删去的i#             result.append(j)#     return result## 这个函数就可以对列表内的元素进行全排列。# permutation([0,1,2])得到[[0,1,2],[0,2,1],[1,0,2],[1,2,0],[2,0,1],[2,1,0]]
原创粉丝点击