目录
问题 A: 二分搜索(递归)
题目描述:
使用递归算法,实现二分搜索。
输入:
多组数据输入,每组第一个数字为数组的长度n,然后输入n个整数,最后输入待查询的值。
输出:
输出待查询值所在的位置,如果没有找到,则返回-1。
思路:经典的二分,模板。
def half(x: int, start: int, end: int):
if start <= end:
mid = (start + end) // 2
if nums[mid] == x:
return mid + 1
elif nums[mid] < x:
return half(x, mid + 1, end)
else:
return half(x, start, mid - 1)
return -1
while True:
try:
nums = list(map(int, input().split()))
n, t = nums.pop(0), nums.pop()
print(half(t, 0, n - 1))
except:
break
问题 B: 二分搜索(非递归)
题目描述:
使用非递归算法,实现二分搜索。
输入:
多组数据输入,每组第一个数字为数组的长度n,然后输入n个整数,最后输入待查询的值。
输出:
输出待查询值所在的位置,如果没有找到,则返回-1。
思路:二分搜索很容易改成非递归,因为二分搜索根本上就是区间的迭代和中间值的判断。
def half(x: int, start: int, end: int):
while start <= end:
mid = (start + end) // 2
if nums[mid] == x:
return mid + 1
elif nums[mid] < x:
start = mid + 1
else:
end = mid - 1
return -1
while True:
try:
nums = list(map(int, input().split()))
n, t = nums.pop(0), nums.pop()
print(half(t, 0, n - 1))
except:
break
问题 C: 例题6-3 冒泡排序
题目描述:
从键盘上输入10个整数,用冒泡法对这10个数进行排序(由小到大)。【必须使用冒泡排序实现】
输入:
以空格分隔的10个整数
输出:
依次输出排好序的10个整数,每个数占一行。
每日一偷鸡:
nums = [int(i) for i in input().split()]
nums.sort()
for num in nums:
print(num)
思路:经典的冒泡排序,利用标签flag,当提前排好的时候及时退出。
nums = [int(i) for i in input().split()]
for i in range(9):
flag = True
for j in range(10 - i - 1):
if nums[j] > nums[j + 1]:
nums[j], nums[j + 1] = nums[j + 1], nums[j]
flag = False
if flag:
break
for num in nums:
print(num)
问题 D: 随机数
题目描述:
有一个rand(n)的函数,它的作用是产生一个在[0,n)的随机整数。现在有另外一个函数,它的代码如下:
int random(int n, int m)
{
return rand(n)+m;
}
显而易见的是函数random(n,m)可以产生任意范围的随机数。现在问题来了,如果我想要产生范围在[a,b)内的一个随机数,那么对应的n,m分别为多少?
输入:
输入的第一行为一个正整数T (T<=1000),表示一共有T组测试数据。
对于每组测试数据包含两个整数a,b (a<=b)。
输出:
对于每组测试数据,输出一行包含两个整数n和m,两个整数中间有一个空格分隔。
思路:找规律,很简单,a就是m的值,a、b区间的大小就是n的值。
t = int(input())
while t > 0:
a, b = map(int, input().split())
print(b - a, a)
t -= 1
问题 E: 快速排序
题目描述:
编程实现快速排序算法,深入理解快速排序算法的基本思想。
输入:
多组输入,每组第一个数字为数组长度,然后输入一个一维整型数组。
输出:
输出快速排序之后的一维整型数组(升序)
思路:了解快速排序的思想,稍微背一背应用不难。
def quick(start: int, end: int):
if start <= end:
i, j = start, end
res = nums[start] # 选择基准
while True:
while j > i and nums[j] >= res:
j -= 1
while i < j and nums[i] <= res:
i += 1
if i < j:
nums[i], nums[j] = nums[j], nums[i]
else:
nums[start], nums[j] = nums[j], nums[start]
break
quick(start, j - 1)
quick(j + 1, end)
while True:
try:
nums = [int(i) for i in input().split()]
n = nums.pop(0)
quick(0, n - 1)
for i in range(n):
print("", nums[i], end='') if i != 0 else print(nums[i], end='')
print()
except:
break
问题 F: 随机化快速排序
题目描述:
使用Java或C++等语言中内置的随机函数实现随机化快速排序,在数组中随机选择一个元素作为分区的主元(Pivot)。
输入:
多组样例输入,每组由一个一维整型数组组成。
输出:
随机化快速排序之后的一维整型数组(升序排列)。
思路:经典快速排序的小变异,为了简化问题,先后对随机选取的基准的右方和左方进行快速排序,所以只要对经典快速排序的算法进行小改变就行。
import random
def quick(start: int, end: int):
if start <= end:
mid = random.randint(start, end) # 基准的下标
res, small, big = nums[mid], end, mid # 记录基准,为简化问题,分别对基准的左右进行快速排序,先对右边
# print(res)
while True: # 对右边快速排序,先找比基准小的数
while small > big and nums[small] >= res:
small -= 1
while big < small and nums[big] <= res:
big += 1
if big < small:
nums[small], nums[big] = nums[big], nums[small]
else:
nums[mid], nums[small], mid, small, big = nums[small], res, small, small - 1, start
break
# print(nums)
while True: # 与右边快速排序类似,不过要先找比基准大的数
while big < small and nums[big] <= res:
big += 1
while small > big and nums[small] >= res:
small -= 1
if big < small:
nums[small], nums[big] = nums[big], nums[small]
else:
if nums[mid] < nums[big]: # 与右边快速排序不同,左边只有满足最后一个数比基准大的时候才交换
nums[mid], nums[big], mid = nums[big], res, big
break
# print(nums)
quick(start, mid - 1)
quick(mid + 1, end)
return
while True:
try:
nums = [int(i) for i in input().split()]
n = nums.pop(0)
quick(0, n - 1)
for i in range(n):
print("", nums[i], end='') if i != 0 else print(nums[i], end='')
print()
except:
break
问题 G: 二分搜索升级版
题目描述:
设a[0:n-1]是已排好序的数组。请改写二分搜索算法,使得当待搜索元素x不在数组中时,返回小于x的最大元素的位置i和大于x的最小元素的位置j;当待搜索元素x在数组中时,返回的i和j相同,均为x在数组中的位置
输入:
多组数据输入,每组第一个数字为数组的长度n,然后输入n个整数,最后输入带查询的值x。
输出:
输出小于x的最大元素的位置i和大于x的最小元素的位置j;当待搜索元素x在数组中时,返回的i和j相同,均为x在数组中的位置
思路:想清楚下标的意义即可,注意下标加一。
def half(x: int, start: int, end: int):
if start <= end:
mid = (start + end) // 2
if nums[mid] > x:
return half(x, start, mid - 1)
if nums[mid] < x:
return half(x, mid + 1, end)
if nums[mid] == x:
return mid + 1, mid + 1
if end == -1:
return -1, start + 1
if start >= n:
return start, -1
return end + 1, start + 1
while True:
try:
nums = list(map(int, input().split()))
n, t = nums.pop(0), nums.pop()
l, r = half(t, 0, n - 1)
print(l, r)
except:
break
问题 H: Strange function
题目描述:
Now, here is a function:
F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100)
Can you find the minimum value when x is between 0 and 100.
输入:
The first line of the input contains an integer T(1<=T<=100) which means the number of test cases. Then T lines follow, each line has only one real numbers Y.(0 < Y <1e10)
输出:
Just the minimum value (accurate up to 4 decimal places),when x is between 0 and 100.
def f(x: float):
return 6 * (x ** 7) + 8 * (x ** 6) + 7 * (x ** 3) + 5 * (x ** 2) - x * y
def three():
start, end = 0, 100
while end - start > 0.0001:
mid = (start + end) / 2
midmid = (mid + end) / 2
if f(mid) < f(midmid):
end = midmid
else:
start = mid
print("%.4f" % f(end))
t = int(input())
while t > 0:
y, t = int(input()), t - 1
three()