题意:
有n个学生,每个学生都有歌唱和相声能力。选择一个集合A,一个集合B。使得集合A里面的最大值与集合B的最大值的差值最小。
思路:
按歌唱能力从大到小枚举,比目前学生歌唱能力强的去表演相声,用multiset维护下,再找到没枚举学生的和目前学生歌唱值最相近的相声值,不要比已经枚举学生的相声能力强。取min
#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int N = 1e5 + 10;
struct node {
ll x, y;
bool operator <(const node &a)const {
return x > a.x;
}
} no[N];
int t, n;
multiset<ll> s1, s2;
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
s1.clear(), s2.clear();
for(int i = 1; i <= n; i++) {
scanf("%lld%lld", &no[i].x, &no[i].y), s1.insert(no[i].y);
}
ll ans = 1e18;
sort(no + 1, no + n + 1);
for(int i = 1; i <= n; i++) {
s1.erase(s1.find(no[i].y));
if(!s2.empty()) {
ans = min(ans, abs(*s2.rbegin() - no[i].x));
}
if(!s1.empty()) {
auto it = s1.lower_bound(no[i].x);
if(it == s1.end())
it--;
if(s2.empty() || *it > *s2.rbegin())
ans = min(ans, abs(*it - no[i].x));
if(it != s1.begin())
it--;
if(s2.empty() || *it > *s2.rbegin())
ans = min(ans, abs(*it - no[i].x));
}
s2.insert(no[i].y);
}
printf("%lld\n", ans);
}
return 0;
}