1 条题解
-
0
处理社恐独行侠(a)
因为 a 类选手极其霸道,必须一人一顶,所以直接消耗 a 顶帐篷。这部分没有任何回旋余地。
处理社牛三人组(b)与随缘百搭党(c)
首先,如果 b 是 3 的倍数(即
b % 3 == 0),那么 b 完全可以自己内部组队,剩下随缘的 c 也可以内部组队。如果 b 不是 3 的倍数,那么 b 除以 3 会有余数(余数为 1 或 2)。这些余下的人必须和 c 类选手拼帐篷。
- 如果余数是 1,说明这个帐篷里还有 2 个空位,需要 c 类出 2 个人来填满。
- 如果余数是 2,说明这个帐篷里还有 1 个空位,需要 c 类出 1 个人来填满。
何时无法满足? 如果
b % 3 != 0,并且 c 类选手的人数不足以填补这个空缺(即b % 3 + c < 3),那么就会导致 b 类的剩余人员无法凑齐 3 人一顶帐篷,此时应输出-1。计算最少帐篷数
如果能够满足上述条件,所有的 b 和 c 最终都可以完美地凑成 3 人一顶的帐篷(或者最多剩 1~2 人单独一顶)。 因此,b 和 c 所需要的帐篷总数可以通过总人数除以 3 向上取整来计算:
(b + c + 2) / 3(在整数除法中,加 2 是为了实现向上取整的常用技巧)。最终答案即为:a 的帐篷数加上(b+c) 凑出的帐篷数。 即:
ans = a + (b + c + 2) / 3;
三、 复杂度分析
- 时间复杂度:O(1)。每组测试用例只需要进行简单的加减乘除和取模运算,非常高效。总时间复杂度为 O(t)。
- 空间复杂度:O(1)。只使用了几个变量来存储数据。
- 数据范围:题目中 a,b,c 最大为 1e9,相加后会超过
int的范围(21亿左右),因此代码中使用了#define int long long,这非常关键。
四、 对应参考代码及注释
cpp
#include <bits/stdc++.h> using namespace std; #define int long long #define PII pair<int,int> void solve() { int a, b, c, ans; // 读入 a, b, c scanf("%lld %lld %lld", &a, &b, &c); // 判断是否无法满足条件 // 如果 b 有余数,且余数加上 c 的人数连 3 人都凑不够 if (b % 3 != 0 && b % 3 + c < 3) { ans = -1; } else { // 否则可以满足条件: // a 必须占 a 顶帐篷 // 剩下的 b 和 c 都可以凑在一起,总人数是 b + c // (b + c + 2) / 3 是向上取整的写法,代表每 3 人一顶帐篷 ans = a + (b + c + 2) / 3; } // 输出答案 printf("%lld\n", ans); } // 因为用了 #define int long long,所以主函数返回值需要改为 signed signed main() { int t; scanf("%lld", &t); while (t--) { solve(); } return 0; }
- 1
信息
- ID
- 1245
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 258
- 已通过
- 35
- 上传者