AtCoder Beginner Contest 223 E - Placing Rectangles(思维)
题目大意:
给你一个 的矩形,问你能不能塞入三个不重叠的面积分别大于等于 的矩形
思路:
首先能够想到贪心的思路,优先处理面积最大的矩形,再在剩余的区域内处理面积次大的矩形。但是这样就陷入了繁琐的分类讨论之中。
此时我们可以考虑类似数学归纳法的思想,先处理问题规模较小时候的情况,看能不能推广到问题规模增大后的情况。
在这里,我们需要给三个矩形分配位置,那么我们首先考虑给两个矩形分配位置的情况。
设两个矩形的面积分别至少为 、。
对于所有合法的位置,一定存在一条平行于 轴或 轴的直线 ,且 满足:
- 不会穿过任何一个矩形的内部
- 将整块区域划分为两部分,每一部分正好能够放置一个矩形
如果该直线 存在,且与 轴平行,则 的取值为 ,然后在剩余的区域内再做划分。平行 轴同理。
不难看出,当题目要求需要划分三个矩形时,我们可以先划分出一个矩形,转化成两个矩形时的情况。
考虑使用 dfs 求解,可以推广到划分 个矩形的情况。
Code:
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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架