jiejiejiang2004

题解:牛客周赛 Round 52 B

B 小红装匣子

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

小红有 \(a\)\(1\times 2\) 大小的物块,\(b\)\(1\times 3\) 的大小的物块,小红想知道能不能填满 \(2\times n\) 大小的匣子。 物块可以旋转使用,可以有剩余。

输入描述:

每个测试文件均包含多组测试数据。第一行输入一个整数 \(T\ (1\le T\le 10^5)\) 代表数据组数,每组测试数据描述如下:
在一行上输入三个整数 \(a,b\)\(n\ (0 \leq a,b \leq 2\times 10^9;1 \leq n \leq 2\times 10^9)\) 表示有 \(a\)\(1\times 2\) 大小的物块,\(b\)\(1\times 3\) 的大小的物块,匣子的大小为 \(2\times n\)

输出描述:

对于每一组测试数据,如果存在一种方式使得物块可以填满匣子,在一行上输出 YES;否则,直接输出 NO

示例1

输入

1
3 2 6

输出

YES

说明

其中一种可行的放置方式如下图所示:
picture

说明!题解我给出两个,本质上是一样的,但是可以给大家看看思路

题解1

第一个题解是我的题解

  1. 首先我假设全部上下分别被 \(1 \times 3\) 的物块填充
  2. 然后剩下的就交给 \(1 \times 2\) 的物块
    • 如果有上下都是空的地方,就让\(1 \times 2\) 的物块打竖放置
    • 如果全部放置之后还有空的话,那这个空位肯定是还差一个相当于一个 \(1 \times 3\) 物块的位置,我可以退一个 \(1 \times 3\) 的物块形成一个 \(1 \times 3\) 的位置然后填充 \(3\)\(1 \times 2\) 的物块
  3. 注意要特判!假如空位无法退格的话说明只有1个\(1 \times 3\) 的物块,那我只要在前面特判一下能不能直接被 \(1 \times 2\) 的物块打竖填满就好了。

代码1

#include <iostream>
#include <algorithm>
#define int long long

int t,n,a,b;

signed main()
{
    std::cin >> t;
    while(t--)
    {
        std::cin >> a >> b >> n;
        int up = n , down = n;
        int tr1 = b/2;
        int tr2 = b/2 + b%2;
        
        if(a >= n)
        {
            std::cout << "YES\n";
            continue;
        }
        
        tr1 = std::min(tr1,up/3);
        tr2 = std::min(tr2,down/3);        
        
        up -= tr1*3;
        down -= tr2*3;
                
        int min = std::min(up,down);
        up -= min;
        down -= min;
        a -= min;
                
        if(up > 0 && tr1 > 0) a -= 3,up = 0;    
        if(down > 0 && tr2 > 0) a -= 3,down = 0;
    
        if(!up && !down && a >= 0) std::cout << "YES\n";
        else std::cout << "NO\n";
    }
    return 0;
}

题解2(最简洁!)

思路来源:CatBiscuit
思路大体如上,但是我们可以发现,在空出来那里退一格不如把凸出来的退掉(减少了特判)
那我只要算:
假设原先的位置先被 \(2 \times 3\) 的物块占满(不超过 \(\frac{b}{2}\) 个),然后剩下的被 \(1 \times 2\) 的物块打竖放满就好了

代码2

#include <iostream>
#include <algorithm>
#define int long long

int t,n,a,b;

signed main()
{
    std::cin >> t;
    while(t--)
    {
        std::cin >> a >> b >> n;
        int need = std::max(n-(b/2)*3,n%3);
        if(a >= need) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

posted on 2024-07-22 14:47  Jiejiejiang  阅读(49)  评论(0编辑  收藏  举报

导航