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


    E - Placing Rectangles

    题目大意:

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

    思路:

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

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

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

    设两个矩形的面积分别至少为 \(A\)\(B\)

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

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

    如果该直线 \(l\) 存在,且与 \(x\) 轴平行,则 \(l\) 的取值为 \(y=\left\lceil\frac{S}{X}\right\rceil\),然后在剩余的区域内再做划分。平行 \(y\) 轴同理。

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

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

    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;
    }
    
  • 相关阅读:
    nginx安装:linux环境下安装包安装
    Effective C++
    Win32 Msg
    C++ 17
    Win32 Threads
    Exceptional C++
    C++11
    STL 分类
    C++类型转换
    红黑树
  • 原文地址:https://www.cnblogs.com/Nepenthe8/p/15939054.html
Copyright © 2020-2023  润新知