题意分析
给定一定数量的 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) 的正方形无法凑出:
而如下
(
k
+
1
)
×
(
k
+
1
)
(k + 1) \times (k + 1)
(k+1)×(k+1),可以凑出:
故本题不具有单调性?
我们发现,奇数具有单调性,偶数就有单调性,故可以分成两次二分,一次二分所有的奇数,再一次二分所有的偶数,最后取最大值即可。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
LL x = 7385137888721, y = 10470245;
bool check(LL u)
{
LL cnt = (u / 2) * (u / 2);
cnt = min(cnt, x);
return u * u <= cnt * 4 + y;
}
int main()
{
LL l = 1, r = 1e9;
while (l < r)
{
LL mid = l + r + 1 >> 1;
if (check(mid + mid % 2))
l = mid;
else
r = mid - 1;
}
LL res1 = l + l % 2;
l = 1, r = 1e9;
while (l < r)
{
LL mid = l + r + 1 >> 1;
if (check(mid + mid % 2) / 2)
l = mid;
else
r = mid - 1;
}
LL res2 = (l + l % 2) / 2;
cout << max(res1, res2) << endl;
return 0;
}
运行结果:
5435122