我的Python学习笔记_Day5 第一周总结练习题

文章目录

  • 第一周总结练习题
  • 习题解答from老师

第一周总结练习题

答案是自己作的,可能有错,望指出,谢谢!
后面会更新老师的解答

"""
1. 一张纸的厚度大约是0.08mm,
对折多少次之后能达到珠穆朗玛峰的高度(8848.13米)?
"""


def fold_to_everest(paper_thickness, target):
    """ 折纸(微米)到指定高度( 米)"""
    count_num = 0
    while paper_thickness < int(target * 1000000):
        paper_thickness <<= 1
        count_num += 1
    return count_num


"""
2. 古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,
小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,
问每个月的兔子对数为多少?
"""


def fibonacci(n):
    """斐波那契数列"""
    num_1 = 1
    num_2 = 1
    for i in range(0, n - 2):
        num_1, num_2 = num_2, num_1 + num_2
    return num_2


"""
3. 将一个正整数分解质因数。例如:输入90,打印出90=2x3x3x5
"""


def disassemble_num(positive_int):
    """分解质因数"""
    nums = []
    j = 2
    finish_flag = False
    while not finish_flag:
        for i in range(j, int(positive_int ** 0.5) + 1):
            if positive_int % i == 0:
                positive_int //= i
                nums.append(i)
                j = i
                break
        else:
            nums.append(positive_int)
            finish_flag = True
    return nums


def print_solution(primary_num):
    """问题解答"""
    nums = disassemble_num(primary_num)
    print(str(primary_num) + ' = ' + str(nums[0]), end='')
    if len(nums) > 1:
        for i in range(1, len(nums)):
            print(' × ' + str(nums[i]), end='')


"""
4. 输入两个正整数m和n,求其最大公约数和最小公倍数。 程序分析:利用辗除法。
"""


def max_gys(int1, int2):
    """返回最大公约数"""
    if int1 > int2:
        int1, int2 = int2, int1
    while True:
        yu = int2 % int1
        if yu == 0:
            return int1
        int2, int1 = int1, yu


def min_gbs(int1, int2):
    """返回最小公倍数"""

    # 分解质因数
    nums1 = disassemble_num(int1)
    nums2 = disassemble_num(int2)

    # 求相对的多余质因数
    for num in nums2:
        if num in nums1:
            nums1.remove(num)

    # 计算最小公倍数
    sum1 = 1
    for num in nums1:
        sum1 *= num
    return sum1 * int2


"""
5. 一个数如果恰好等于它的因子之和,这个数就称为 "完数 "。
例如6=1+2+3.  编程 找出1000以内的所有完数
"""


def return_ys(int1):
    """返回因数"""
    d_num = []
    for i in range(1, int1):
        if int1 % i == 0:
            d_num.append(i)
    return d_num


def check_perfect_number(int1):
    """返回完数"""
    d_num = return_ys(int1)
    if sum(d_num) == int1:
        return True


def get_perfect_num(start, end):
    """返回指定范围内的完数"""
    p_nums = []
    for i in range(start, end + 1):
        if check_perfect_number(i):
            p_nums.append(i)
            continue
    else:
        return p_nums


"""
6. 输入某年某月某日,判断这一天是这一年的第几天? 
程序分析:以3月5日为例,应该先把前两个月的加起来,
然后再加上5天即本年的第几天,特殊情况,
闰年且输入月份大于3时需考虑多加一天
"""


def check_loop_year(year):
    """检测是否闰年"""
    if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
        return True


normal_year = {
    1: 31,
    2: 28,
    3: 31,
    4: 30,
    5: 31,
    6: 30,
    7: 31,
    8: 31,
    9: 30,
    10: 31,
    11: 30,
    12: 31}
loop_year = {
    1: 31,
    2: 29,
    3: 31,
    4: 30,
    5: 31,
    6: 30,
    7: 31,
    8: 31,
    9: 30,
    10: 31,
    11: 30,
    12: 31}


def calculate_days(year, month, day):
    """计算天数"""

    # 根据是否闰年确定每个月的天数
    days_data = normal_year
    if check_loop_year(year):
        days_data = loop_year

    # 计算天数
    sum_days = 0
    for i in range(1, month):
        sum_days += days_data[i]
    sum_days += day

    return sum_days


"""
7. 某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,
加密规则如下:每位数字都加上5,然后用和除以10的余数代替该数字,
再将第一位和第四位交换,第二位和第三位交换。
求输入的四位整数加密后的值
"""


def encrypt_num(num):
    """加密数字"""
    str_num = str(num)
    num_list = [(int(i) + 5) % 10 for i in str_num]
    num_list[0], num_list[3] = num_list[3], num_list[0]
    num_list[1], num_list[2] = num_list[2], num_list[1]

    str_num = [str(i) for i in num_list]
    sum_str = ''
    for i in str_num:
        sum_str += i
    return int(sum_str)


"""
8. 获取第n个丑数。 什么是丑数: 因子只包含2,3,5的数
"""


def clear_1235(list1):
    """列表清除2"""
    while True:
        if 1 in list1:
            list1.remove(1)
        else:
            break
    while True:
        if 2 in list1:
            list1.remove(2)
        else:
            break
    while True:
        if 3 in list1:
            list1.remove(3)
        else:
            break
    while True:
        if 5 in list1:
            list1.remove(5)
        else:
            break
    return list1


def get_ug_num(n):
    """返回第n个丑数"""

    # 由于上面的题写过获取质因数的代码,这里直接copy来,懒得编新的解题方法了
    ug_nums = []
    main_num = 1
    while len(ug_nums) <= n:

        ys_nums = disassemble_num(main_num)  # 获取质因数

        ys_nums = clear_1235(ys_nums)  # 去因数里的1235

        if not ys_nums:
            ug_nums.append(main_num)

        main_num += 1

    return ug_nums[n - 1]

习题解答from老师

# 1.一张纸的厚度大约是0.08mm,对折多少次之后能达到珠穆朗玛峰的高度(8848.13米)?
# 循环次数不确定,使用while循环; 每次对折后的高度是原来厚度的2倍
count = 0  # 保存次数
height = 0.08
while True:
    height *= 2
    count += 1
    if height >= 8848.13:
        break
print('对折%d次' % count)

# 3. 将一个正整数分解质因数。例如:输入90,打印出90=2x3x3x5。
factor = 2  # 保存因数
num = 90
print(num, '=', end='')
while num != 1:
    while num % factor == 0:
        num //= factor
        if num != 1:
            print(factor, '+', end='')
        else:
            print(factor)
            break
    factor += 1


# 4. 输入两个正整数m和n,求其最大公约数和最小公倍数。 程序分析:利用辗除法。
m = 90
n = 35
# 先保证m中保存两个数中较小的那个数
if m > n:
    m, n = n, m

# 求最大公约数
if n % m == 0:
    print('m和n的最大公约数为:', m)
else:
    for num in range(m-1, 1, -1):
        if m % num == 0 and n % num == 0:
            print('m和n的最大公约数为:', num)
            break
    else:
        print('m和n的最大公约数为:', 1)

你可能感兴趣的:(Python学习笔记)