项目欧拉编号338

时间:2011-08-28 19:37:04

标签: python algorithm math

我被困在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)。显然,新的矩形区域与旧矩形的区域相同。

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

这种方法的主要问题是可以用两种不同的方式制作一个新的矩形。例如,(9,8)可以转换为(6,12)(12,6) d=3以及d-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
无论F有多快,G(10 12 )都需要太长时间才能解决。我认为有必要使用某种筛分算法,我们遍历所有x&lt; 10 12 计算有多少(w,h)满足h <= w <= 10 12 ,x |(w * h),x!= h和( wx)| w或(xh)| x。

我认为O(n 2/3 )算法必须是可能的...但我被困在这里!


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

编辑2 :我认为按主要因素考虑区域是一个死胡同。那是因为有10个 24 不同的区域。具有素数区域的矩形具有0个解,具有半素面积的矩形具有1个解,如果其中一个素数为2,否则它们具有0个解。但是,单独计算所有半素溶液将花费太长时间,因为我们需要计算所有质数p,使得2 * p <1。 10 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 <0。 x&lt; N,0&lt; h&lt; N + 1,x!= h,max(h,x 2 / h)&lt; w&lt; N + 1,x | wh和x-h | h。

我认为我们应该假设一些素数p除以x,w,h甚至x-h,然后看看我们可以推断出其他变量。如果效果很好,可以考虑p k 表示任意k。

1 个答案:

答案 0 :(得分: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可用于表示法并使用算法:)

您方面的进展是什么?