• 「网易官方」极客战记(codecombat)攻略-沙漠-最大公约数-tiresome-gcd


    (点击图片进入关卡)

    并非所有算法都是相同的。

    简介

    两个或多个非全为零的整数的最大公约数( gcd ),指的是除这些整数能除尽的最大正整数。

    要进入宝库,你需要说出密码。我们的情报员获得了密码相关的两个数字密匙。 要确定密码,你需要求出这两个数字的最大公约数。

    要求出最大公约数,从大到小枚举小于给定数字的所有可能数字,是最简单的方法(但较慢)。 如果两个数字都能被当前数字整除,没有余数,那它就是最大公约数了。

    或许,还有别的方法?

    默认代码

    # 计算秘密数字并进入财政部。
    # 这两个人知道密码的关键。
    friends = hero.findFriends()
    number1 = friends[0].secretNumber
    number2 = friends[1].secretNumber
    # 只是为了确保第一个数字更大。
    if number2 > number1:
        swap = number1
        number1 = number2
        number2 = swap

     

    # 这是简单但慢的功能找到gcd。
    def bruteforceGCD (a, b):
        hero.say("朴素的算法。")
        cycles = 0
        # 我们列举了所有可能的除数。
        counter = b
        while True:
            cycles += 1
            if cycles > 100:
                hero.say("计算是困难的。我累了。")
                break
            # 如果两个数字都有 "counter" 除数。
            if a % counter == 0 and b % counter == 0:
                break
            counter -= 1
        hero.say("我使用了 " + cycles + " 周期")
        return counter

     

    # 这是找到gcd的聪明方式。
    def euclidianGCD (a, b):
        cycles = 0
        while b:
            cycles += 1
            swap = b
            b = a % b
            a = swap
        hero.say("我使用了 " + cycles + " 周期")
        return a

     

    # 也许你需要使用另一个功能?
    secretNumber = bruteforceGCD(number1, number2) # ∆
    hero.moveXY(48, 34)
    hero.say(secretNumber)
    # 财政部是开放的(我希望如此)!去那儿!
    hero.moveXY(68, 34)

    概览

    求最大公约数 gcd 的朴素算法可以称作蛮力算法,因为它需要蛮力枚举所有可能的答案。 如果有两个数字 A 和 B ( A > B ),那我们就从 B 开始,逐次减一。 这就需要从 B 算到 1 ,总共 B 个周期。对于当前的关卡,这会是 10 ** 15 周期。

    数字很小时这还没关系,但如果数字很大(例如:2**100),且我们需要求出多组数字的最大公约数(密码学中经常要用到这些),情况会如何呢? 就算是最强的计算机,也会碰到麻烦。更何况,能找到更优解决方案的时候,我们不希望浪费宝贵的计算资源。

    在默认代码中,你可以看到函数 euclidianGCD 。它所实现的是欧几里得算法,能更快速地求出最大公约数。 欧几里得算法基于的原理是,在将大数替换为它与小数之间的差值后,两个数的最大公约数会保持不变。 现在你并不需要理解算法本身。这里我们主要要讲的是,求解同一个问题通常会有多种算法,不同算法效率也会不同。

    P.S.: 如果你想了解欧几里得算法的详细内容,请参阅维基百科页面Wikipedia

    最大公约数 解法

    # 计算秘密数字并进入财政部。
    # 这两个人知道密码的关键。
    friends = hero.findFriends()
    number1 = friends[0].secretNumber
    number2 = friends[1].secretNumber
    # 只是为了确保第一个数字更大。
    if number2 > number1:
        swap = number1
        number1 = number2
        number2 = swap

     

    # 这是简单但慢的功能找到gcd。
    def bruteforceGCD (a, b):
        hero.say("朴素的算法。")
        cycles = 0
        # 我们列举了所有可能的除数。
        counter = b
        while True:
            cycles += 1
            if cycles > 100:
                hero.say("计算是困难的。我累了。")
                break
            # 如果两个数字都有 "counter" 除数。
            if a % counter == 0 and b % counter == 0:
                break
            counter -= 1
        hero.say("我使用了 " + cycles + " 周期")
        return counter

     

    # 这是找到gcd的聪明方式。
    def euclidianGCD (a, b):
        cycles = 0
        while b:
            cycles += 1
            swap = b
            b = a % b
            a = swap
        hero.say("我使用了 " + cycles + " 周期")
        return a

     

    # 也许你需要使用另一个功能?
    secretNumber = bruteforceGCD(number1, number2) # ∆
    hero.moveXY(48, 34)
    hero.say(secretNumber)
    # 财政部是开放的(我希望如此)!去那儿!
    hero.moveXY(68, 34)
     
    本攻略发于极客战记官方教学栏目,原文地址为:
  • 相关阅读:
    MySQL性能调优my.cnf详解
    PHP调试工具Xdebug安装配置教程
    【转载】Zend Studio 10正式版注册破解
    SQL 大全(3)
    SQL 大全(1)
    JQuery方法
    修改 C:Users[account name] 目录名称
    wordmate 词典安装
    Python3 之 import 和 当前目录
    初遇 dotcloud
  • 原文地址:https://www.cnblogs.com/codecombat/p/13328083.html
Copyright © 2020-2023  润新知