【题解】CF2170C Quotient and Remainder

题意

给定正整数 \(n, k\),以及两个长为 \(n\) 的数列 \(\{q_n\}, \{r_n\}\)。若存在 \(x, y\in 1, k, y < x\) 使得 \(x = q_iy + r_j(i\neq j)\),则称其为一个匹配,求在保证每个 \(i\) 仅出现在一个匹配中的情况下最多有几组匹配。

思路

注意到 \(y\) 在 \(1, k\) 中任取,为了使 \(x\) 最小化,我们取 \(y = (r_j + 1)\)。所以:

\x = q_i(r_j + 1) + r_j (i\\neq j) \\

考虑贪心,先对 \(\{q_n\}, \{r_n\}\) 排序,让最小的 \(q_i\) 匹配最大的 \(r_j\),如果生成的 \(x\) 不满足小于等于 \(k\),则换一个更小的 \(r_j\),直到 \(q_i \geq k\) 或没有 \(r_j\) 可以再匹配,即可求出最大匹配个数。

那么这个做法为什么是对的呢?考虑从反面思考:如果 \(q_i\) 不去匹配最大(满足可行)的 \(r_j\),而是匹配小一些的 \(r_j'\),那么显然这组匹配是有冗余的。也就是说如果把 \(r_j'\) 让给一个更大的 \(q_i'\),有可能再促成一组匹配。所以对于每个 \(p_i\),它都应该匹配最大的可行的 \(r_j\)。

代码

代码如下。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 2e5 + 5;
int T, n;
ll k, q[N], r[N];
int main() {
    scanf("%d", &T);
    while (T--) {
        int cnt = 0;
        scanf("%d%lld", &n, &k);
        for (int i = 1; i <= n; i++)
            scanf("%lld", &q[i]);
        for (int i = 1; i <= n; i++)
            scanf("%lld", &r[i]);
        sort(q + 1, q + 1 + n), sort(r + 1, r + 1 + n);
        int lo = 1, hi = n;
        while (1) {
            if (q[lo] >= k)
                break;
            // 如果此时的 q 值已经大于等于 k,那么没有必要继续匹配,一定不能成立
            ll x = q[lo] * (r[hi] + 1) + r[hi];
            bool f = false;
            while (x > k) { // 如果此时 x > k,尝试换更小的 r
                if (hi - 1 == 0) { // 此时已经没有 r 可以匹配,退出
                    f = true;
                    break;
                }
                hi--;
                x = q[lo] * (r[hi] + 1) + r[hi];
            }
            if (x <= k) // 如果尝试之后匹配到了合适的 r
                cnt++, lo++, hi--;
            if (lo == n + 1 || hi == 0 || f) // 如果没有匹配到,退出
                break;
        }
        printf("%d\n", cnt);
    }
    return 0;
}
相关推荐
Tisfy9 小时前
LeetCode 0678.有效的括号字符串:O(n)+O(1)一次遍历
算法·leetcode·字符串·题解·贪心·括号匹配
lvwangshu1 天前
登录日志 题解
数据结构·线段树·题解·技巧·性质题·思维好题·细节题
漂流瓶jz1 天前
UVA-1610 聚会游戏 题解答案代码 算法竞赛入门经典第二版
数据结构·c++·算法·题解·aoapc·算法竞赛入门经典·uva
漂流瓶jz1 天前
UVA-12545 比特变换器 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·题解·aoapc·算法竞赛入门经典·uva·12545
lvwangshu3 天前
T2 最长上升子序列(lis)题解
动态规划·题解·技巧·性质题·思维好题
lvwangshu3 天前
T1 称重(weight)题解
题解·贪心·总结·技巧·性质题·思维好题
Tisfy3 天前
LeetCode 0020.有效的括号:栈匹配
算法·leetcode·字符串·题解·括号匹配
王老师青少年编程4 天前
2026年9月GESP真题及题解(C++八级):末班车
c++·题解·真题·gesp·八级·2026年9月·末班车
朔北之忘 Clancy5 天前
2025 CSP-J 第二轮真题解析
c++·青少年编程·题解·noip·csp·信奥赛·noi