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
时间限制:500ms内存限制:32000kb
解题思路:
1.判断一个数可不可以是主元,就是判断这个数是否大于这个数后面所有数的最小值,小于这个数前面所有数的最大值。
2.注意输出格式
3.注意只有一个元素的时候
程序代码:
l = list(map(int,input().split()))
length = len(l)
ll = []
if len(l) == 1:
print(1)
print(l[0])
else:
for i in range(1,length-1):
if l[i] > max(l[:i]) and l[i] < min(l[i+1:]):
ll.append(l[i])
if l[0] < l[1]:
ll.append(l[0])
if l[-1] > l[-2]:
ll.append(l[-1])
ll.sort()
print(len(ll))
print(" ".join([str(i) for i in ll]))
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):
- # code here
- pass
- print(firstBadVersion(N))
时间限制:500ms内存限制:32000kb
解题思路1:
暴力从头查找,判断是不是坏的版本。
程序代码1:
N = int(input())
isBadVersion = eval(input())
def firstBadVersion(n):
for i in range(1,n+1):
if(isBadVersion(i)):
return i
print(firstBadVersion(N))
解题思路2:
运用二分查找来提高效率。
程序代码2:
N = int(input())
isBadVersion = eval(input())
def firstBadVersion(n):
left = 1
right = n
while(left<right):
mid = left + (right - left) // 2
if (isBadVersion(mid)):
right = mid
else:
left = mid + 1
return left
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
时间限制:500ms内存限制:32000kb
解题思路:
1.先判断是插入排序,还是归并排序。
2.然后针对这个排序进行下一步排序。
程序代码:
def check(lst1,lst2):
flag = 0
for i in range(len(lst2)-1):
if lst2[i] > lst2[i+1]:
flag = i + 1
break
if lst1[flag:] == lst2[flag:]: # 插入排序
result = sorted(lst1[:flag+1])+lst2[flag+1:] # 再迭代一轮的结果
return True,result
else: # 归并排序
cnt = 2 # 归并的数量
result = lst2
while result == lst2: # 不断归并排序直到顺序发送变化
sub_lst = [sorted(lst2[i:i+cnt]) for i in range(0,len(lst2),cnt)]
result = [num for sub in sub_lst for num in sub]
cnt *= 2
return False,result
lst1 = [int(i) for i in input().split()]
lst2 = [int(i) for i in input().split()]
num = len(lst1)
flag,next_list = check(lst1,lst2)
if flag:
print("Insertion Sort")
else:
print("Merge Sort")
print(" ".join([str(i) for i in next_list]))