题解:CF1949B Charming Meals

· · 题解

题目传送门

update:2024.5.21 删除反抄袭

题意

给与两个数组 ab,将其中的数两两匹配,要求匹配后每组数字的差值中最小值最大,求这个值。

思路

首先将 ab 升序排序,此时取任意 p 满足 1 \le p \le n,可证对于 1 \le i \le p,最佳匹配为 a_ib_{p + i} 匹配, b_ia_{p + i} 匹配。

证明部分

若存在 i + p \le j \le n 使得 a_ib_j 匹配优于 a_ib_{p + i} 匹配,则改变匹配使得a_ib_j 匹配, $a_{j - p}

#### 证毕 所以只需要枚举每一个 $p$ ,取答案最大值即可。复杂度为 ${O} (n^ 2)$. ## 代码部分 ```cpp // Problem: Charming Meals // Contest: Luogu // URL: https://www.luogu.com.cn/problem/CF1949B // Memory Limit: 250 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org) #include<bits/stdc++.h> using namespace std; const int N = 1e5 + 10; const int M = 5e3 + 10; int n, a[N], b[N], vis[M], ans; // bool check(int mid) // { // memset(vis, 0, sizeof vis); // if(max(abs(a[1] - b[n]), abs(a[n] - b[1])) < mid) return false; // cout << "mid = " << mid << '\n'; // for(int i = 1; i <= n; i ++) // { // int cnt = upper_bound(b + 1, b + n + 1, a[i]) - b, f1 = 0, f2 = 0; // for(int j = cnt; j <= n; j ++) if(b[j] - a[i] >= mid && !vis[j]) {vis[j] = true, f1 = j; break;} // for(int j = cnt - 1; j >= 1; j --) if(a[i] - b[j] >= mid && !vis[j]) {vis[j] = true, f2 = j; break;} // cout << "f1 = " << b[f1] << " f2 = " << b[f2] << '\n'; // if(!f1 && !f2) return false; // else if((f1 && !f2) || (!f1 && f2)) continue; // else // { // if(b[f1] - a[i] > a[i] - b[f2]) vis[f1] = false; // else vis[f2] = false; // } // } // return true; // } int work(int t) { int minn = 2e9 + 10; for(int i = 1; i <= t; i ++) minn = min(minn, abs(a[i] - b[n - t + i])); for(int i = t + 1; i <= n; i ++) minn = min(minn, abs(b[i - t] - a[i])); return minn; } signed main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int T; cin >> T; while(T --) { cin >> n; ans = -1; for(int i = 1; i <= n; i ++) cin >> a[i]; for(int i = 1; i <= n; i ++) cin >> b[i]; sort(a + 1, a + n + 1), sort(b + 1, b + n + 1); for(int i = 1; i <= n; i ++) ans = max(ans, work(i)); cout << ans << '\n'; } return 0; } ```