AtCoder Beginner Contest 223 E - Placing Rectangles(思维)

E - Placing Rectangles

题目大意:

给你一个 X×Y 的矩形,问你能不能塞入三个不重叠的面积分别大于等于 A,B,C 的矩形

思路:

首先能够想到贪心的思路,优先处理面积最大的矩形,再在剩余的区域内处理面积次大的矩形。但是这样就陷入了繁琐的分类讨论之中。

此时我们可以考虑类似数学归纳法的思想,先处理问题规模较小时候的情况,看能不能推广到问题规模增大后的情况。

在这里,我们需要给三个矩形分配位置,那么我们首先考虑给两个矩形分配位置的情况。

设两个矩形的面积分别至少为 AB

对于所有合法的位置,一定存在一条平行于 x 轴或 y 轴的直线 l,且 l 满足:

  • 不会穿过任何一个矩形的内部
  • 将整块区域划分为两部分,每一部分正好能够放置一个矩形

如果该直线 l 存在,且与 x 轴平行,则 l 的取值为 y=SX,然后在剩余的区域内再做划分。平行 y 轴同理。

不难看出,当题目要求需要划分三个矩形时,我们可以先划分出一个矩形,转化成两个矩形时的情况。

考虑使用 dfs 求解,可以推广到划分 n 个矩形的情况。

Code:
Copy
int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); ll x, y; vector<ll> s(3); cin >> x >> y; for (auto &i : s) { cin >> i; } auto sol = [&](auto self, ll x, ll y, int id) { if (id == 3) { return true; } if (x == 0 || y == 0) { return false; } bool ok = false; ll t1 = (s[id] + y - 1) / y; if (t1 <= x) { ok |= self(self, x - t1, y, id + 1); } ll t2 = (s[id] + x - 1) / x; if (t2 <= y) { ok |= self(self, x, y - t2, id + 1); } return ok; }; bool gok = false; sort(s.begin(), s.end()); do { gok |= sol(sol, x, y, 0); } while (next_permutation(s.begin(), s.end())); cout << (gok ? "Yes" : "No") << "\n"; return 0; }
posted @   Nepenthe8  阅读(87)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示