P9713 「QFOI R1」抱抱 题解
P9713 「QFOI R1」抱抱 题解
Sol
前置知识:长方体体积公式:\(V = abh\)。
我们知道,切割掉 \(x \le k\) 的部分就是把 \(a\) 减去 \(k\),切割掉 \(y \le k\) 的部分就是把 \(b\) 减去 \(k\),切割掉 \(z \le k\) 的部分就是把 \(c\) 减去 \(k\)。但是这里要考虑重合的部分,比如切掉 \(x \le 3\) 的部分再切掉 \(x \le 5\) 的部分,那么第二次 \(a\) 只能减去 \(5 - 3 = 2\)。我们可以定义一个存 \(k\) 最大值的变量 \(maxa\),如果 \(maxa < k\),那么就减去 \(max(c - (k - maxa),\ 0)\),并把 \(maxa = k\)。每一次切割完后输出新的 \(a\),\(b\),\(c\) 相乘的结果即可。还有,一定要开 long long!
code
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
using ll = long long;
const int kMaxN = -1, kInf = (((1 << 30) - 1) << 1) + 1;
ll a, b, c, m, op, k, maxa1, maxa2, maxa3;
// maxa1 存切割 a 时的 k,maxa2 存切割 b 时的 k,maxa3 存切割 c 时的 k
int main() {
cin >> a >> b >> c >> m; // 输入 a, b, c, m
for (; m; -- m) { // 循环,等于 while (m --)
cin >> op >> k; // 输入 op, k
if (op == 1) { // 如果切割 a
(maxa1 < k) && (a = max(a - (k - maxa1), 0ll)) && (maxa1 = k);
// 如果没有重合的部分 > 0(k - maxa1),那么把 a 减去重合的部分(这里取 max 是因为不放心)并更新 maxa1
} else if (op == 2) {
(maxa2 < k) && (b = max(b - (k - maxa2), 0ll)) && (maxa2 = k);
// 如果没有重合的部分 > 0(k - maxa2),那么把 b 减去重合的部分(这里取 max 是因为不放心)并更新 maxa2
} else {
(maxa3 < k) && (c = max(c - (k - maxa3), 0ll)) && (maxa3 = k);
// 如果没有重合的部分 > 0(k - maxa3),那么把 c 减去重合的部分(这里取 max 是因为不放心)并更新 maxa3
}
cout << a * b * c << '\n'; // 输出 a * b * c(体积公式)
}
return 0;
}

浙公网安备 33010602011771号