1. 1 抓交通肇事犯
一辆卡车违反交通规则,撞人后逃跑。现场有三人目击该事件,但都没有记住车号,只记下了车号的一些特征。甲说:牌照的前两位数字是相同的;乙说:牌照的后两位数字是相同的,但与前两位不同;丙是数学家,他说:4位的车号刚好是一个整数的平方。
请根据以上线索求出车号。
if __name__ == '__main__':for i in range(10): # 牌照的前两位数字for j in range(10): # 牌照的后两位数字if i != j: # 前两位不同x = 1000 * i + 100 * i + 10 * j + jfor m in range(31, 100): # 4位的车号刚好是一个整数的平方if m * m == x:print("车牌号为:", x)
1.2 兔子产子
有一对兔子,从出生后的第3个月起每个月都生一对兔子。小免子长到第3个月后每个月又生一对兔子,假设所有的兔子都不死,问n个月内每个月的兔子总对数为多少?
if __name__ == '__main__':rb1 = 1 # 第一个月的兔子对数rb2 = 1 # 第二个月的兔子对数n = int(input("请输入您查询月份:"))if n <= 2:print(f"前 {n} 个月的兔子总对数为 1 对")else:for i in range(3, n + 1): # 从第3个月开始计算sum_rb = rb1 + rb2rb2 = rb1rb1 = sum_rbprint(f'{n} 个月后兔子总对数为:{sum_rb}')
1.3 牛顿选代法求方程根
编写用牛顿迭代法求方程根的函数。方程为ax^3+bx^2+cx+d=0,系数a、b、c、d由主函数输入,求x在1附近的一个实根。求出根后,由主函数输出。
def newton_method(a, b, c, d, x0, tol=1e-6, max_iter=100):"""牛顿迭代法求解方程 ax^3 + bx^2 + cx + d = 0 的根:param a: 三次项系数:param b: 二次项系数:param c: 一次项系数:param d: 常数项:param x0: 初始猜测值:param tol: 容差,默认 1e-6:param max_iter: 最大迭代次数,默认 100:return: 求得的实根"""def f(x):return a * x ** 3 + b * x ** 2 + c * x + d # 定义方程 f(x)def f_prime(x):return 3 * a * x ** 2 + 2 * b * x + c # 定义导数 f'(x)x = x0 # 初始猜测值for i in range(max_iter):fx = f(x)fpx = f_prime(x)if abs(fx) < tol: # 如果 f(x) 接近 0,则认为找到了根return xif fpx == 0: # 如果导数为 0,无法继续迭代raise ValueError("导数为 0,无法继续迭代")x = x - fx / fpx # 牛顿迭代公式return x # 返回最终的近似根if __name__ == '__main__':# 输入方程的系数a = float(input("请输入系数 a: "))b = float(input("请输入系数 b: "))c = float(input("请输入系数 c: "))d = float(input("请输入系数 d: "))# 初始猜测值为 1 附近的点x0 = 1.0# 调用牛顿迭代法求解try:root = newton_method(a, b, c, d, x0)print(f"方程的一个实根为: {root:.6f}")except ValueError as e:print(e)
1.4 百钱百鸡
中国古代数学家张丘建在他的《算经》中提出了一个著名的“百钱百鸡问题”:一只公鸡值五钱,一只母鸡值三钱,三只小鸡值一钱,现在要用百钱买百鸡,请问公鸡、母鸡、小鸡各多少只?
if __name__ == '__main__':for x in range(20):for y in range(33):for z in range(100):if 5 * x + 3 * y + (z / 3 == 100):if x + y + z == 100:print(x, y, z)
1.5 借书方案知多少
小明有5本新书,要借给A、B、C三位小朋友,若每人每次只能借1本,则可以有多少种不同的借法?
if __name__ == '__main__':total = 0for a in range(1, 6):for b in range(1, 6):for c in range(1, 6):if a != b and b != c and a != c:total += 1print(f"{a},{b},{c}")print(f"{total}种")
1.6 打鱼还是晒网
中国有句俗语叫“三天打鱼两天晒网”。某人从1990年1月1日起便开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。
def is_leap_year(year):"""判断某一年是否为闰年:param year: 年份:return: True 是闰年,False 不是闰年"""return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)def days_from_1990(year, month, day):"""计算从 1990 年 1 月 1 日到给定日期的总天数:param year: 目标年份:param month: 目标月份:param day: 目标日期:return: 总天数"""# 每个月的天数month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]total_days = 0# 计算 1990 年到目标年份之间的天数for y in range(1990, year):total_days += 366 if is_leap_year(y) else 365# 计算目标年份中 1 月到目标月份之间的天数for m in range(1, month):total_days += month_days[m - 1]if m == 2 and is_leap_year(year): # 闰年 2 月多一天total_days += 1# 加上目标日期的天数total_days += day - 1 # 减去 1,因为 1990 年 1 月 1 日是第 1 天return total_daysdef fishing_or_drying(year, month, day):"""判断某一天是“打鱼”还是“晒网”:param year: 目标年份:param month: 目标月份:param day: 目标日期:return: "打鱼" 或 "晒网""""total_days = days_from_1990(year, month, day)remainder = total_days % 5 # 5 天为一个周期if remainder < 3: # 余数为 0、1、2 表示“打鱼”return "打鱼"else: # 余数为 3、4 表示“晒网”return "晒网"if __name__ == '__main__':# 输入目标日期year = int(input("请输入年份: "))month = int(input("请输入月份: "))day = int(input("请输入日期: "))total_days = days_from_1990(year,month,day)# 判断是“打鱼”还是“晒网”result = fishing_or_drying(year, month, day)print(f"{year}年{month}月{day}日,这一天相差{total_days}天,这一天在{result}。")
1.7 最佳存款方案
假设银行一年整存零取的月息为0.63%。现在某人手中有一笔钱,他打算在今后5年中的每年年底取出1000元,到第5年时刚好取完,请算出他存钱时应存入多少。
if __name__ == '__main__':m = 0.0063money = 0.0for i in range(1,6):money = (money + 1000) / (1 + m * 12)print(f"存钱时应存入{money}")
1.8 冒泡排序
对N个整数(数据由键盘输入)进行升序排列。
if __name__ == '__main__':# 获取用户输入并去除首尾的空白字符x = input().strip()# 以空白字符为分隔符将输入字符串分割成多个字符串,再把这些字符串转换为整数,形成列表a = list(map(int, x.split()))# 获取列表的长度n = len(a)# 冒泡排序for i in range(n):for j in range(0, n - i - 1):if a[j] > a[j + 1]:# 交换相邻元素的位置a[j], a[j + 1] = a[j + 1], a[j]print(a)
1.9 折半查找
N个有序整数数列已放在一维数组中,利用二分查找法查找整数m在数组中的位置。若找到,则输出其下标值;反之,则输出“Not be found!"
def binary_search(arr, m):# 初始化左右指针left, right = 0, len(arr) - 1while left <= right:# 计算中间元素的索引mid = (left + right) // 2if arr[mid] == m:# 找到目标值,返回其下标return midelif arr[mid] < m:# 目标值在右半区间,更新左指针left = mid + 1else:# 目标值在左半区间,更新右指针right = mid - 1# 未找到目标值return -1if __name__ == "__main__":# 从键盘输入有序整数数列,以空格分隔input_str = input("请输入有序整数数列(以空格分隔):").strip()arr = list(map(int, input_str.split()))# 从键盘输入要查找的整数m = int(input("请输入要查找的整数 m:"))# 调用二分查找函数result = binary_search(arr, m)if result != -1:print(f"整数 {m} 在数组中的下标是:{result}")else:print("Not be found!")
1.10 数制转换
给定一个M进制的数x,实现对x向任意一个非M进制的数的转换。
def m_to_decimal(x, m):"""将 M 进制的数 x 转换为十进制数:param x: M 进制的数,字符串类型:param m: M 进制:return: 十进制数"""decimal_num = 0power = len(x) - 1for digit in x:if digit.isdigit():value = int(digit)else:# 处理字母表示的数字,如 A 表示 10,B 表示 11 等value = ord(digit.upper()) - ord('A') + 10decimal_num += value * (m ** power)power -= 1return decimal_numdef decimal_to_n(decimal_num, n):"""将十进制数转换为 N 进制的数:param decimal_num: 十进制数:param n: 目标进制:return: N 进制的数,字符串类型"""if decimal_num == 0:return '0'result = ''while decimal_num > 0:remainder = decimal_num % nif remainder < 10:result = str(remainder) + resultelse:# 处理大于 9 的余数,用字母表示result = chr(ord('A') + remainder - 10) + resultdecimal_num //= nreturn resultdef convert_number(x, m, n):"""将 M 进制的数 x 转换为 N 进制的数:param x: M 进制的数,字符串类型:param m: M 进制:param n: 目标进制:return: N 进制的数,字符串类型"""# 先将 M 进制的数转换为十进制数decimal_num = m_to_decimal(x, m)# 再将十进制数转换为 N 进制的数return decimal_to_n(decimal_num, n)# 示例使用
if __name__ == "__main__":x = input("请输入 M 进制的数: ")m = int(input("请输入当前进制 M: "))n = int(input("请输入目标进制 N: "))result = convert_number(x, m, n)print(f"{m} 进制的数 {x} 转换为 {n} 进制的数是: {result}")