原題連結
HINT 1:
給定升序陣列 \(a,b\),已知 \(b_i \geq a_i\) , 請任意排列 \(a,b\) 使得
- \(b_i \geq a_i\) 對所有 \(i\) 都成立
- 最大化 \(\min(b_i-a_i)\)
請問該如何排列?
答案是就讓 \(a,b\) 升序排列,舉反例可以任意交換兩個 \(b_i,b_j\) 驗證
HINT 2:
假設我們已知最優配對和最優值 \(k\),那麼一定存在 \(t\) 個小配對使得 \(a_i+k \leq b_i\),\(n-t\) 個大配對使得 \(a_i-k \geq b_i\)
- 對於小配對,為了最優,一定是最小的 \(t\) 個 \(a_i\) 去配對最大的 \(t\) 個 \(b_i\)
- 對於大配對,為了最優,一定是最大的 \(n-t\) 個 \(a_i\) 去配對最小的 \(n-t\) 個 \(b_i\)
題解
根據上述提示,我們遍歷所有的 \(t\) 即可
code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll a[5005], b[5005];
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
ll t;
cin >> t;
while (t--)
{
ll n;
cin >> n;
for (ll i = 1; i <= n; i++) cin >> a[i];
for (ll i = 1; i <= n; i++) cin >> b[i];
sort(a + 1, a + 1 + n);
sort(b + 1, b + 1 + n);
ll ans = 0;
for (ll len = 0; len <= n; len++) // 有len個小配對
{
ll flag = 1;
ll val = 2e15;
for (ll i = 1; i <= len; i++)
{
if (a[i] > b[n - len + i]) flag = 0;
else val = min(val, b[n - len + i] - a[i]);
}
for (ll i = 1; i <= n - len; i++)
{
if (b[i] > a[i + len]) flag = 0;
else val = min(val, a[i + len] - b[i]);
}
if (flag) ans = max(ans, val);
}
cout << ans << '\n';
}
return 0;
}