【问题标题】:Project Euler Number 338欧拉计划编号 338
【发布时间】:2011-08-28 19:37:03
【问题描述】:

我被困在 Project Euler problem 338 上。这是我到目前为止所做的......

让我们用xy分别表示一个矩形(x,y)。要形成新的矩形,您可以考虑使用 d 步沿对角线向下切割一种楼梯(如问题描述中所示)。但是要形成一个新的矩形,必须满足以下条件:d|x(d-1)|y(d+1)|y。然后新的矩形变为(x/d*(d-1), y/(d-1)*d)(x/d*(d+1), y/(d+1)*d)。显然新的矩形区域与旧矩形的区域相同。

这足以确认 G(10)=55G(1000)=971745 通过循环所有相关的 d 并将所有新矩形添加到一个集合中,注意只计算一次 (x,y)(y,x)

这种方法的主要问题是可以用两种不同的方式创建一个新的矩形。例如,(9,8) 可以转换为 (6,12)(12,6)d=3d-1d+1 除以 y。或者(4,4) 的另一个示例转换为(2,8)(8,2),分别为d=2d=1

然后我有幸阅读了this blog post。它消除了通过搜索一侧来检查重复项的需要。

def F(w, h):
    if w&1 and h&1: return 0
    if w<h: w,h = h,w

    r = 0
    x = 1
    while x**2 <= w*h:
        if (w*h)%x!=0 or x==h:
            x += 1
            continue

        if w%(w-x)==0 or x%(x-h)==0:
            r += 1

        x += 1

    return r

def G(N):
    s = 0
    for w in range(1, N+1):
        for h in range(1, w+1):
            s += F(w,h)

    return s

G(1012) 将需要太长的时间来解决,无论 F 有多快。我认为有必要使用某种筛选算法,我们循环遍历所有 x 12 计算有多少 (w,h) 满足 h 12 sup>, x|(w*h), x != h 和 (w-x)|w 或 (x-h)|x。

我认为 O(n2/3) 算法一定是可能的......但我被困在这里!


编辑:我无法访问论坛,因为我无法解决它。这就是我寻求帮助的原因。我已经完成了大多数其他问题,现在想解决这个问题!

编辑 2:我认为按主要因素考虑这些区域是一条死胡同。那是因为有 1024 个不同的区域。具有素数面积的矩形有 0 个解,如果素数之一是 2,则具有半素数面积的矩形有 1 个解,否则它们有 0 个解。但是单独计算所有半素数解决方案会花费太长时间,因为我们需要计算所有素数 p 使得 2*p 24 这是不可行的。

编辑 3:我已经精简了代码:

def G(N):
    s = 0
    for x in range(1, N):
        for h in range(1, N+1):
            if x==h: continue
            for w in range(max(h, x**2//h), N+1):
                if (w*h)%x==0 and x%(w-x)==0 and x%(x-h)==0:
                    s -= 1

    for x in range(1, N):
        for h in range(1, N+1):
            if x==h: continue
            for w in range(max(h, x**2//h), N+1):
                if (w*h)%x==0 and w%(w-x)==0:
                    s += 1

    for x in range(1, N):
        for h in range(1, N+1):
            if x==h: continue
            for w in range(max(h, x**2//h), N+1):
                if (w*h)%x==0 and h%(x-h)==0:
                    s += 1

    return s

我不认为破解蛮力代码会起作用。请记住,我们只计算这三个子问题中的每一个的解 (x, w, h) 就足够了。最后一个这样的求和将具有约束 0 2/h)

我认为我们应该从假设某个素数 p 整除 x、w、h 甚至 x-h 开始,然后看看我们可以从其他变量中推断出什么。如果效果很好,可以考虑使用 pk 来表示任意 k。

【问题讨论】:

  • 如果您遇到困难,请尝试另一个。正如网站所说,“如果你不能解决它,那么你就无法解决它!”.
  • 您可能还想在 math.stackexchange.com 上提问
  • 此外,在您将解决方案提交给 Project Euler 后,您可以访问该问题的留言板;可能有人已经找到了最佳算法。
  • 另一种思考方式是根据数字的素因数,因此在 9 * 4 示例中,您有 3*3 和 2*2,它们当然可以排列成其他三个独特的方式,3 和 3*2*2、2 和 3*3*2、3*2 和 3*2。计算唯一排列是否更快?我不知道这种方法是否有效,但它是解决问题的另一种方法。祝你好运。
  • 我不明白为什么会有 +10 票。欧拉计划是关于自己解决问题的。

标签: python algorithm math


【解决方案1】:

我还没有解决方案,但是对于 Python 来说有些有趣。我意识到 Python 可以用作算法符号的便捷工具!基本上我写了一个类似于你的程序,并开始在逻辑上转换程序,使结果保持不变。我想出了

def order(x,y):
    if x>=y:
        return (x,y)
    else:
        return (y,x)

N=1000
num=set()
for n in range(1, N+1):
    for a in range(1,N//n+1):
        for b in range(1,N//(n+1)+1):
            if a==b: continue
            num.add((order(a*n,b*(n+1)), order(b*n,a*(n+1))))

print(N, len(num))

显然蛮力甚至超过 10^12 的简单循环是不可行的,但也许通过这种算法,人们可以在某些时候找到一个封闭形式的表达式。如果不是因为 num 的设置字符,它是可行的。也许可以通过这种方式找到重复点。

这可能是一个死胡同,但 Python 可用于表示法并与算法一起工作仍然很酷:)

你有什么进展吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多