题意分析
给定一定数量的 2 × 2 2 \times 2 2×2 的方块和一定数量的 1 × 1 1 \times 1 1×1 的方块,问能拼出的最大正方形的边长为多少。
显而易见的是,如果图越大,就越难拼出来,所以具有二段性,可以考虑二分算法?
- 大的正方形可以拼出来,小的就可以拼出来,更大的不一定可以拼出来,但是其实是错误的,以下给出反例。
可能存在某个 k × k ( k % 2 = 1 ) k \times k(k \% 2 = 1) k×k(k%2=1) 的正方形无法凑出(一定需要 2 × k − 1 2 \times k - 1 2×k−1 个 1 × 1 1\times1 1×1 的正方形):
而如下
(
k
+
1
)
×
(
k
+
1
)
(k + 1) \times (k + 1)
(k+1)×(k+1),可以凑出(方块的总面积
≥
(
k
+
1
)
×
(
k
+
1
)
\geq (k+1)\times(k+1)
≥(k+1)×(k+1) 即可):
故本题不具有单调性?
我们发现,奇数具有单调性,偶数具有单调性,故可以分成两次二分,一次二分所有的奇数,再一次二分所有的偶数,最后取最大值即可。
x, y = 7385137888721, 10470245
def check(u):
cnt = (u // 2) * (u // 2)
cnt = min(cnt, x)
return u * u <= cnt * 4 + y
l, r = 1, int(1e18)
while l < r:
mid = l + r + 1 >> 1
if check(mid + mid % 2):
l = mid
else:
r = mid - 1
res1 = l + l % 2
l, r = 1, int(1e18)
while l < r:
mid = l + r + 1 >> 1
if check((mid + mid % 2) // 2):
l = mid
else:
r = mid - 1
res2 = (l + l % 2) // 2
print(max(res1, res2))
运行结果:
5435122