题解:牛客周赛 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
说明
其中一种可行的放置方式如下图所示:
说明!题解我给出两个,本质上是一样的,但是可以给大家看看思路
题解1
第一个题解是我的题解
- 首先我假设全部上下分别被 \(1 \times 3\) 的物块填充
- 然后剩下的就交给 \(1 \times 2\) 的物块
- 如果有上下都是空的地方,就让\(1 \times 2\) 的物块打竖放置
- 如果全部放置之后还有空的话,那这个空位肯定是还差一个相当于一个 \(1 \times 3\) 物块的位置,我可以退一个 \(1 \times 3\) 的物块形成一个 \(1 \times 3\) 的位置然后填充 \(3\) 个 \(1 \times 2\) 的物块
- 注意要特判!假如空位无法退格的话说明只有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) 编辑 收藏 举报