《程序员的算法趣题》-(日)增井敏克 Python解题 -- (Q10)

《程序员的算法趣题》-(日)增井敏克 , 书中为69 道数学谜题编写了解题程序, 编程语言为:Ruby,JavaScript,C语言。有兴趣的同学,可以购书阅读~

在此更新个人编写的Python版,仅供学习使用。(运行环境:Python3.6)

Q10 轮盘的最大值

      流传较广的轮盘数字排布和设计有“欧式规则”和“美式规则”两种。下面我们要找出在这些规则下,“连续 n 个数字的和”最大的位置。

      举个例子,当 n = 3 时,按照欧式规则得到的和最大的组合是 36,11, 30 这个组合,和为 77;而美式规则下则是 24, 36, 13 这个组合,得到的和为73。

                                                                 

                                                                                  欧式规则

欧式规则
        0, 32, 15, 19, 4, 21, 2, 25, 17, 34, 6, 27, 13, 36, 11, 30, 8, 23, 10, 5, 24, 16, 33, 1, 20, 14, 31, 9, 22, 18, 29, 7, 28, 12, 35, 3, 26
美式规则
       0, 28, 9, 26, 30, 11, 7, 20, 32, 17, 5, 22, 34, 15, 3, 24, 36, 13, 1, 00, 27, 10, 25, 29, 12, 8, 19, 31, 18, 6, 21, 33, 16, 4, 23, 35, 14, 2


问题
      当 2 ≤ n ≤ 36 时,求连续 n 个数之和最大的情况,并找出满足条件"欧式规则下的和小于美式规则下的和"的 n 的个数。

import time

european = [0, 32, 15, 19, 4, 21, 2, 25, 17, 34, 6, 27, 13, 36, 11, 30, 8, 23, 10, 5, 24, 16, 33, 1, 20, 14, 31, 9, 22,
            18, 29, 7, 28, 12, 35, 3, 26]
american = [0, 28, 9, 26, 30, 11, 7, 20, 32, 17, 5, 22, 34, 15, 3, 24, 36, 13, 1, 00, 27, 10, 25, 29, 12, 8, 19, 31,
            18, 6, 21, 33, 16, 4, 23, 35, 14, 2]

# 常规算法
def max_sum(cal_list, n):
    res_max = 0
    for start_pos in range(len(cal_list)):
        if start_pos+n > len(cal_list):
            n_list = cal_list[start_pos:]
            n_list += cal_list[:start_pos+n-len(cal_list)]
        else:
            n_list = cal_list[start_pos:start_pos+n]
        n_sum = sum(n_list)
        if n_sum > res_max:
            res_max = n_sum
    return res_max

# 蠕虫算法
def worm_sum(cal_list, n):
    res_max = cal_sum = sum(cal_list[:n])
    for start_pos in range(0, len(cal_list)):
        end_pos = (start_pos + n) % len(cal_list)
        cal_sum = cal_sum - cal_list[start_pos] + cal_list[end_pos]
        if cal_sum > res_max:
            res_max = cal_sum
    return res_max

def calc_result(use_method):
    start_time = time.time()
    result_number = 0
    for n in range(2, 37):
        european_max = use_method(european, n)
        american_max = use_method(american, n)
        if european_max < american_max:
            result_number += 1

    print("满足条件的n的个数为:%s, (耗时 %0.5f s)" % (result_number, time.time()-start_time))

calc_result(max_sum)
calc_result(worm_sum)

运行结果:

            满足条件的n的个数为:9, (耗时 0.00398 s)
           满足条件的n的个数为:9, (耗时 0.00101 s)

猜你喜欢

转载自blog.csdn.net/cloudly89/article/details/84559944