1 条题解

  • 0
    @ 2026-5-16 22:42:43

    A. 矩形的正方形 题解

    题目理解

    给定三个矩形,尺寸分别为 l1×b1l_1 \times b_1l2×b2l_2 \times b_2l3×b3l_3 \times b_3,满足:

    • l3l2l1l_3 \le l_2 \le l_1
    • b3b2b1b_3 \le b_2 \le b_1

    要求判断是否能将这三个矩形拼成一个正方形,要求:

    • 矩形不能旋转(即长和宽不能互换)
    • 矩形边与正方形边平行
    • 矩形之间不能重叠

    解题思路

    由于矩形不能旋转,且边长已经按从大到小排序,我们可以枚举所有可能的拼接方式。

    核心观察

    三个矩形拼成正方形,只有两种基本布局方式:

    布局一:三个矩形并排放置(长度方向一致)
    此时正方形的边长等于最长矩形的长,三个矩形的宽之和等于正方形边长。

    布局二:两个矩形并排放,第三个矩形放在它们上面(或下面)
    此时需要满足宽度和高度的匹配关系。


    详细分析

    情况1:三个矩形的长都相等

    l1=l2=l3=Ll_1 = l_2 = l_3 = L

    此时有两种子情况:

    子情况1.1:三个矩形并排放
    正方形的边长 =L= L
    三个矩形的宽之和 =b1+b2+b3= b_1 + b_2 + b_3 必须等于 LL
    即:L=b1+b2+b3L = b_1 + b_2 + b_3

    子情况1.2:两个矩形并排放,第三个矩形放在它们上面
    设正方形边长为 SS

    • 下面两个矩形并排放,它们的长之和必须等于 SS,且它们的高相等(都为 b1b_1?需要仔细分析)

    实际上,在这种布局中:

    • 由于 l1=l2=l3=Ll_1 = l_2 = l_3 = L,如果两个矩形并排放,它们的宽度方向(即 bb 方向)会成为正方形的高
    • 正方形边长 S=L+b2S = L + b_2?等等,这不对

    正确分析:因为所有矩形的长都是 LL,所以:

    • 如果两个矩形并排放(比如矩形2和矩形3),它们的长 LL 会成为正方形的高
    • 第三个矩形(矩形1)放在它们旁边或上面
    • 实际上可行的布局是:矩形1竖着放(高 =l1=L= l_1 = L,宽 =b1= b_1),矩形2和矩形3横着并排放在矩形1旁边(它们的高 =b2= b_2b3b_3,但需要 b2=b3b_2 = b_3 才能并排放)

    等等,这样分析很乱。让我们系统化:

    正确解法:由于标程已经给出了简洁的判断逻辑,我们来解读它。


    标程逻辑解读

    标程的核心判断函数 check()

    auto check = [&] () {
        if (l1 == l2 && l2 == l3) 
            return (l1 == b1 + b2 + b3 || (b1 == b2 + b3 && 2*l1 == b1));
        if (l2 == l3) 
            return (b2 + b3 == b1 && b1 == l2 + l1);
        return false;
    };
    

    情况1:l1=l2=l3l_1 = l_2 = l_3

    此时三个矩形的长度相等,设为 LL

    子情况1.1:三个矩形并排放
    正方形边长 =L= L
    三个矩形宽度之和 =b1+b2+b3= b_1 + b_2 + b_3
    条件:L=b1+b2+b3L = b_1 + b_2 + b_3

    子情况1.2:两个矩形并排放,第三个放在它们上面
    此时,两个宽度较小的矩形(b2b_2b3b_3)并排放,放在下面,它们的宽度之和 =b2+b3= b_2 + b_3 作为正方形的边长;上面的矩形(b1b_1)横跨整个宽度,但注意:上面的矩形长度方向是 l1=Ll_1 = L,所以它的长度会成为正方形的高度。

    更准确地说:

    • 下面两个矩形并排放,它们的高度都是 LL(因为长度方向作为高度),宽度分别是 b2b_2b3b_3,总宽度 =b2+b3= b_2 + b_3
    • 上面一个矩形横着放,它的宽度 =b1= b_1,高度 =L= L
    • 正方形边长 S=b2+b3=b1S = b_2 + b_3 = b_1(上面矩形的宽度必须等于下面总宽度)
    • 同时,正方形的高度 S=L+L=2LS = L + L = 2L?不对,下面矩形高度是 LL,上面矩形高度也是 LL,总高度 =2L= 2L

    实际上,这种布局是:下面两个矩形并排放(它们的高都是 LL,宽分别是 b2b_2b3b_3),上面一个矩形(高 LL,宽 b1b_1)放在它们上面。
    总宽度 =b2+b3= b_2 + b_3,总高度 =L+L=2L= L + L = 2L
    要形成正方形,需要:
    b2+b3=2Lb_2 + b_3 = 2Lb1=2Lb_1 = 2L?但条件写的是 b1=b2+b3b_1 = b_2 + b_32L=b12L = b_1

    所以条件:b1=b2+b3b_1 = b_2 + b_32L=b12L = b_1


    情况2:l2=l3l_2 = l_3(但 l1l_1 可能不同)

    此时矩形2和矩形3的长度相等。

    可行布局:矩形1和矩形2、3中的一个并排放,另一个放在上面

    具体来说,标程判断的条件是:

    • b2+b3=b1b_2 + b_3 = b_1
    • b1=l2+l1b_1 = l_2 + l_1

    这意味着:

    • 矩形1的宽度 b1b_1 等于矩形2和矩形3的宽度之和
    • 矩形1的宽度也等于 l1+l2l_1 + l_2

    这种布局的解释:

    • 矩形2和矩形3并排放(它们的高度都是 l2l_2,因为长度方向作为高度)
    • 矩形1放在它们旁边(竖着放,高度 =l1= l_1,宽度 =b1= b_1
    • 总高度 =l1= l_1(矩形1的高度)需要等于 l2l_2(矩形2、3的高度)?这不对

    实际上正确的几何解释:

    • 矩形2和矩形3并排放,它们的高度都是 l2l_2(长度方向),宽度分别是 b2b_2b3b_3,总宽度 =b2+b3= b_2 + b_3
    • 矩形1放在它们上面(横着放),它的高度 =b1= b_1,宽度 =l1= l_1
    • 要形成正方形,需要:总宽度 =b2+b3=b1= b_2 + b_3 = b_1(矩形1的高度),且总高度 =l2+b1=l1+l2= l_2 + b_1 = l_1 + l_2?混乱了

    让我们重新理解标程:标程先检查 l1==l2==l3l_1 == l_2 == l_3,然后检查 l2==l3l_2 == l_3
    l2==l3l_2 == l_3 时,条件 b2+b3==b1b_2 + b_3 == b_1b1==l2+l1b_1 == l_2 + l_1 可以直接验证。

    这个条件对应的布局是:

    • 矩形2和矩形3上下叠放(或左右并排放),矩形1放在旁边
    • 由于输入保证了 b3b2b1b_3 \le b_2 \le b_1l3l2l1l_3 \le l_2 \le l_1,所以这种条件恰好覆盖了一种特殊布局

    算法步骤

    对于每个测试用例:

    1. 调用 check() 函数,判断当前方向下是否可行
    2. 如果不可行,交换所有矩形的长和宽(相当于允许旋转所有矩形,但题目说不允许旋转?注意标程这样做的原因:输入保证 lil_i 从大到小、bib_i 从大到小,但实际放置时,我们可以选择将矩形的"长"作为高度或宽度。交换后相当于重新解释哪个是长哪个是宽,但保持排序性质)
    3. 再次调用 check(),如果可行输出 "YES",否则 "NO"

    时间复杂度

    每个测试用例 O(1)O(1),总时间复杂度 O(t)O(t)


    完整代码

    #include <iostream>
    using namespace std;
    
    int main() {
        int t;
        cin >> t;
        
        int l1, b1, l2, b2, l3, b3;
        
        auto check = [&] () {
            // 情况1:三个矩形长度相等
            if (l1 == l2 && l2 == l3) {
                // 子情况1:并排放
                if (l1 == b1 + b2 + b3) return true;
                // 子情况2:两个并排放,一个放上面
                if (b1 == b2 + b3 && 2 * l1 == b1) return true;
                return false;
            }
            // 情况2:后两个矩形长度相等
            if (l2 == l3) {
                return (b2 + b3 == b1 && b1 == l2 + l1);
            }
            return false;
        };
        
        while (t--) {
            cin >> l1 >> b1 >> l2 >> b2 >> l3 >> b3;
            
            if (check()) {
                cout << "YES\n";
            } else {
                // 交换所有矩形的长和宽
                swap(l1, b1);
                swap(l2, b2);
                swap(l3, b3);
                
                if (check()) {
                    cout << "YES\n";
                } else {
                    cout << "NO\n";
                }
            }
        }
        
        return 0;
    }
    

    验证示例

    以样例第2个测试用例:l1=5,b1=3,l2=5,b2=1,l3=5,b3=1l_1=5,b_1=3,l_2=5,b_2=1,l_3=5,b_3=1

    第一次检查:l1=l2=l3=5l_1=l_2=l_3=5
    l1=5l_1 = 5b1+b2+b3=3+1+1=5b_1+b_2+b_3 = 3+1+1 = 5
    输出 "YES"

    以样例第4个测试用例:l1=8,b1=5,l2=3,b2=5,l3=3,b3=3l_1=8,b_1=5,l_2=3,b_2=5,l_3=3,b_3=3

    第一次检查:l1l2l_1 \ne l_2l2l3l_2 \ne l_3l2=3,l3=3l_2=3,l_3=3,所以 l2=l3l_2=l_3
    检查:b2+b3=5+3=8b_2+b_3=5+3=8b1=5b_1=5858 \ne 5
    交换后:l1=5,b1=8,l2=5,b2=3,l3=3,b3=3l_1=5,b_1=8,l_2=5,b_2=3,l_3=3,b_3=3
    现在 l2=5,l3=3l_2=5,l_3=3 不相等,且 l1=5,l2=5,l3=3l_1=5,l_2=5,l_3=3 也不满足 l2=l3l_2=l_3
    输出 "NO"

    • 1

    信息

    ID
    7137
    时间
    1000ms
    内存
    256MiB
    难度
    2
    标签
    递交数
    1
    已通过
    1
    上传者