Project Euler 247

Project Euler 247

题目

Squares under a hyperbola

Consider the region constrained by 1x and 0y1x.

Let S1 be the largest square that can fit under the curve.

Let S2 be the largest square that fits in the remaining area, and so on.

Let the index of Sn be the pair (left, below) indicating the number of squares to the left of Sn and the number of squares below Sn.

The diagram shows some such squares labelled by number.

S2 has one square to its left and none below, so the index of S2 is (1,0).

It can be seen that the index of S32 is (1,1) as is the index of S50.

50 is the largest n for which the index of Sn is (1,1).

What is the largest n for which the index of Sn is (3,3)?

解决方案

假设当前正方形的左下角顶点为 (x0,y0),那么通过以下步骤可以计算这个正方形的最大边长:

  1. 联立两个方程:y=1x,yy0=xx0,最终解得出右上角的定点为 (x,y)
  2. 这个正方形的边长为 xx0

为了进行加速,代码实现没有使用优先队列,而是使用了两次深度优先搜索:

  • 第一次用于找到坐标为 (3,3) 的最小正方形,假设边长 l
  • 第二次用于找到比 l 大的所有正方形边长。

两次搜索完成后,找到的个数加 1 就是答案。

由于第二次深度优先搜索递归深度太大,故使用非递归进行模拟。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
N = 3
M = 3
min_size = 1
ans = 1


def cal(x, y):
b = y - x
return (-b + (b ** 2 + 4) ** 0.5) / 2 - x


def dfs(x, y, fx, fy):
if fx > N or fy > M:
return
size = cal(x, y)
global min_size
if fx == N and fy == M and size < min_size:
min_size = size
dfs(x + size, y, fx + 1, fy)
dfs(x, y + size, fx, fy + 1)


dfs(1, 0, 0, 0)
st = [(1, 0)]
while len(st) > 0:
x, y = st.pop()
size = cal(x, y)
if size > min_size:
ans += 1
st.append((x + size, y))
st.append((x, y + size))
print(ans)

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
Ujimatsu Chiya 微信 微信
Ujimatsu Chiya 支付宝 支付宝