【题解】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;
}
相关推荐
Tisfy13 天前
LeetCode 0453.最小操作次数使数组元素相等:两次遍历(反向思维)
算法·leetcode·题解·遍历·反向思维
孤独的Bochi13 天前
# [CSP-S 2026] 迁徙 / migrate 题解
题解
Tisfy13 天前
LeetCode 3665.统计镜子反射路径数目:三个动态规划数组
leetcode·动态规划·代理模式·题解
漂流瓶jz14 天前
UVA-1612 猜名次 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·题解·排序·aoapc·算法竞赛入门经典
lvwangshu17 天前
P15569 [COCI 2025/2026 #5] 结构 / Struktura 题解
矩阵·题解·dp·推导题·矩阵加速
lvwangshu20 天前
T3 涂鸦带师 题解
题解·贪心·倍增·技巧·思维好题·断环成链
Tisfy22 天前
LeetCode 3644.排序排列:不对则与(脑筋急转弯)
数据结构·算法·leetcode·题解·位运算
lvwangshu23 天前
P8981 「DROI」Round 1 距离 题解
动态规划·图论·题解·dp·树形dp·技巧·换根dp·性质题·思维好题
lvwangshu24 天前
P17723 [SCP-S 2026] 函数 / func 题解
题解·双指针·技巧·性质题·思维好题·推导题
Tisfy24 天前
LeetCode 3863.将一个字符串排序的最小操作次数:分类讨论(一次遍历)——简单易懂版
算法·leetcode·字符串·题解·分类讨论