python第七周答案_数据结构与算法Python版第七周OJ作业

1 快速排序主元(10分)

题目内容:

著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元(中值),通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。 给定划分后的N个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元?

例如给定的排列是[1, 3, 2, 4, 5]。则:

1 的左边没有元素,右边的元素都比它大,所以它可能是主元;

尽管 3 的左边元素都比它小,但其右边的 2 比它小,所以它不能是主元;

尽管 2 的右边元素都比它大,但其左边的 3 比它大,所以它不能是主元;

类似原因,4 和 5 都可能是主元。

因此,有 3 个元素可能是主元。

输入格式:

一行数个整数的排列,由空格分隔

输出格式:

在第 1 行中输出有可能是主元的元素个数;在第 2 行中按递增顺序输出这些元素,其间以 1 个空格分隔,行首尾不得有多余空格。

输入样例:

1 3 2 4 5

输出样例:

3

1 4 5

解题思路:

判断一个数是不是主元,就是看它左边的数是不是都比它小,右边的数是不是都比它大,注意单独讨论首尾元素且要考虑只有一个元素的情况

程序代码:

def prin_element(a):

b = []

if len(a) == 1:

b = a

else:

for i in range(1,len(a)-1):

if a[i] > max(a[:i]) and a[i] < min(a[i+1:]):

b.append(a[i])

if a[0] < min(a[1:]):

b.insert(0,a[0])

if a[-1] > max(a[:-1]):

b.append(a[-1])

print(len(b))

print(' '.join([str(i) for i in b]))

lst = list(map(int,input().split()))

prin_element(lst)

2 第一个坏版本(10分)

题目内容:

现在有同一个产品的N个版本,编号为从1至N的整数;其中从某个版本之后所有版本均已损坏。现给定一个函数isBadVersion,输入数字N可判断该版本是否损坏(若损坏将输出True);请找出第一个损坏的版本。

注:有时isBadVersion函数运行速度很慢,请注意优化查找方式

输入格式:

两行

第一行为整数,为产品号总数N

第二行为给定的判断函数,使用有效的Python表达式给出,可使用eval读取

输出格式:

一行数字,表示第一个损坏的版本

输入样例:

50

lambda n:n>=30

输出样例:

30

解题思路:

用例有运行时间限制,采取二分法来加快查找速度,注意当中间元素为损坏版本时,它也有可能是第一个损坏的版本

程序代码:

N = int(input())

isBadVersion = eval(input())

def firstBadVersion(n):

first = 1

last = n

while first < last:

mid = (first + last) // 2

if isBadVersion(mid):

last = mid # 这里不能用mid-1,因为mid也有可能是第一个坏版本

else:

first = mid + 1

return first

print(firstBadVersion(N))

3 插入与归并(10分)

题目内容:

给出如下定义:

插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。

归并排序进行如下迭代操作:首先将原始序列看成 N 个只包含 1 个元素的有序子序列,然后每次迭代归并两个相邻的有序子序列,直到最后只剩下 1 个有序的序列。

现给定原始序列和由某排序算法产生的中间序列,请你判断该算法究竟是哪种排序算法?

输入格式:

两行由空格分隔的数字,其对应长度相等的列表

其中第一行代表未排序的列表,第二行是排序算法过程中某一步的中间列表

输出格式:

首先在第 1 行中输出Insertion Sort表示插入排序、或Merge Sort表示归并排序;然后在第 2 行中输出用该排序算法再迭代一轮的结果序列。题目保证每组测试的结果是唯一的。数字间以空格分隔,且行首尾不得有多余空格

输入样例:

3 1 2 8 7 5 9 4 0 6

1 3 2 8 5 7 4 9 0 6

输出样例:

Merge Sort

1 2 3 8 4 5 7 9 0 6

输入样例2:

3 1 2 8 7 5 9 4 6 0

1 2 3 7 8 5 9 4 6 0

输出样例2:

Insertion Sort

1 2 3 5 7 8 9 4 6 0

解题思路:

先观察插入排序后的列表,可以看出列表前一部分为有序列表,后一部分与插入排序前完全相同,通过这个特点判断是否为插入排序,否则为归并排序

程序代码:

def check(lst1,lst2):

position = 0

for i in range(len(lst1)-1):

if lst2[i+1]

position = i+1

break

if lst1[position:] == lst2[position:]: # 判断是否为插入排序

lst2 = sorted(lst2[:position+1])+lst2[position+1:]

print('Insertion Sort')

print(' '.join([str(i) for i in lst2]))

else: # 否则为归并排序

cnt = 2

lst = lst2

while lst == lst2: # 对排序后的列表不断进行归并排序直到列表改变

lst = [sorted(lst2[i:i+cnt]) for i in range(0,len(lst2),cnt)]

lst = [num for sub_lst in lst for num in sub_lst]

cnt *= 2

print('Merge Sort')

print(' '.join([str(i) for i in lst]))

lst1 = list(map(int,input().split()))

lst2 = list(map(int,input().split()))

check(lst1, lst2)

你可能感兴趣的:(python第七周答案)