diff --git a/src/10/19/P9124.cpp b/src/10/19/P9124.cpp new file mode 100644 index 0000000..7264630 --- /dev/null +++ b/src/10/19/P9124.cpp @@ -0,0 +1,115 @@ +#include +#include +#include +#include +// 使用 long long 防止溢出,特别是 c_i 可以达到 2*10^18 +using ll = long long; + +#define sl static inline + +const ll maxn = 100 + 5; +ll T, n; +// tc, tm 定义为 long long 以匹配 c_i 的数量级,防止计算中溢出 +ll tc, tm; +ll a[maxn], b[maxn], c[maxn]; + +// 检查总花费 S 是否可行 +// 替换了原来错误的 checkall 函数 +sl bool checkall(ll S) { + // 设 cookie 制作时间减少 x,则 muffin 减少 S-x + // 我们需要寻找是否存在一个 x 满足所有约束 + + // 约束1: x 必须在花费和时间限制内 + // x >= 0, S-x >= 0 => 0 <= x <= S + // tc - x >= 1 => x <= tc - 1 + // tm - (S-x) >= 1 => x >= S - tm + 1 + ll lower_x = std::max(0LL, S - tm + 1); + ll upper_x = std::min(S, tc - 1); + + // 如果初始约束已经无解,则该 S 不可行 + if (lower_x > upper_x) { + return false; + } + + // 约束2: 满足所有朋友的时间要求 + // a_i * (tc - x) + b_i * (tm - (S-x)) <= c_i + // (b_i - a_i) * x <= c_i - a_i*tc - b_i*tm + b_i*S + for (int i = 1; i <= n; ++i) { + // 使用 ll 处理中间计算,防止溢出 + ll rhs = c[i] - a[i] * tc - b[i] * tm + b[i] * S; + + if (a[i] < b[i]) { + // b_i - a_i > 0, x <= floor(rhs / (b_i - a_i)) + // C++ 整数除法对于负数结果会向0取整,需要特殊处理 + ll diff = b[i] - a[i]; + ll new_upper; + if (rhs >= 0) { + new_upper = rhs / diff; + } else { + // 等价于 floor(x/y) 对于 x<0, y>0 + new_upper = (rhs - diff + 1) / diff; + } + upper_x = std::min(upper_x, new_upper); + } else if (a[i] > b[i]) { + // b_i - a_i < 0, x >= ceil(rhs / (b_i - a_i)) + // 两边同乘 -1,变为 (a_i - b_i) * x >= -rhs + // x >= ceil(-rhs / (a_i - b_i)) + ll diff = a[i] - b[i]; + ll neg_rhs = -rhs; + ll new_lower; + if (neg_rhs >= 0) { + // 等价于 ceil(x/y) 对于 x>=0, y>0 + new_lower = (neg_rhs + diff - 1) / diff; + } else { + new_lower = neg_rhs / diff; + } + lower_x = std::max(lower_x, new_lower); + } else { // a[i] == b[i] + // x 的系数为 0,不等式变为 0 <= rhs + if (rhs < 0) { + // 此不等式无解,说明该总花费 S 不可行 + return false; + } + } + } + + // 如果所有约束下的 x 的可行范围存在 (即下界 <= 上界),则该 S 可行 + return lower_x <= upper_x; +} + + +sl void solve() { + std::cin >> n >> tc >> tm; + for (ll i = 1; i <= n; i++) { + std::cin >> a[i] >> b[i] >> c[i]; + } + + // 二分答案: 最小总花费 + // 最小花费为 0, 最大花费为 tc+tm-2 (使制作时间都变为1) + ll left = 0, right = tc + tm - 2, ans = right + 1; + + // 注意这里二分循环条件的修改 + // [left, right] 是搜索区间 + while (left <= right) { + ll mid = left + (right - left) / 2; + if (checkall(mid)) { + // 如果 mid 是一个可行的花费,我们记录它,并尝试寻找更小的花费 + ans = mid; + right = mid - 1; + } else { + // 如果 mid 不可行,我们需要增加花费 + left = mid + 1; + } + } + std::cout << ans << "\n"; +} + +int main() { + std::ios_base::sync_with_stdio(false); + std::cin.tie(nullptr); + + std::cin >> T; + while (T--) { + solve(); + } +} diff --git a/src/10/20/P7556.cpp b/src/10/20/P7556.cpp new file mode 100644 index 0000000..4ebfc67 --- /dev/null +++ b/src/10/20/P7556.cpp @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include +#include +using ll = int64_t; +#define sl static inline +ll T,n,arr[10],ans; +std::setv; + +sl void solve(){ + ans=0; + std::cin>>n; + v.clear(); + for(ll i=1;i<=n;i++){ + std::cin>>arr[i]; + v.emplace(arr[i]); + } + for(ll i=1;i<=n;i++){ + for(ll j=i+1;j<=n;j++){ + v.emplace(std::abs(arr[i]-arr[j])); + } + } + for(auto a = v.begin();a!=v.end();a++){ + for(auto b=a;b!=v.end();b++){ + for(auto c=b;c!=v.end();c++){ + for(ll i=1;i<=n;i++){ + if(!(arr[i]==*a || arr[i]==*b || arr[i]==*c || arr[i]==*a+*b||arr[i]==*a+*c||arr[i]==*b+*c||arr[i]==*a+*b+*c)){ + goto nxt; + } + } + ans++; + nxt:; + } + } + } + std::cout<>T; + while(T--){ + solve(); + } +} \ No newline at end of file