Welcome Party
Time Limit: 4000/4000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 391 Accepted Submission(s): 75
Problem Description
The annual welcome party of the Department of Computer Science and Technology is coming soon! Many students have been applying to show up at the welcome party, and every one of them can choose to sing a song or play crosstalk. This troubles the chief director a lot: how to arrange the program list, such that every student can have a chance to show up on the stage, and the satisfactory value of audiences is maximized?
To cope with this problem, the director proposes a model. In this model, every student has two attributes: the singing ability and crosstalking ability. The satisfactory value of audiences to singings is the maximum singing ability among all students that choose to sing a song; similarly, the satisfactory value to crosstalks is the maximum crosstalking ability among all students that choose play crosstalk. The strange thing is, the overall satisfactory value to the whole party is negatively related to the absolute difference between the satisfactory values to singings and crosstalks. The problem is, what is the minimum possible absolute difference between the satisfactory values of the two types of programs?
Note that:
- every student should choose exactly one type of programs to play;
- at least one student should sing a song, and at least one student should play crosstalk.
Input
The first line of input consists of a single integer T (1≤T≤70), the number of test cases.
Each test case starts with a line of a single integer n (2≤n≤100000), denoting the number of students applying to show up on the stage. Then follow n lines, each containing two integers x and y (0≤x,y≤1018), denoting the singing ability and crosstalking ability of a student.
It is guaranteed that the sum of n over all test cases never exceeds 1000000.
Output
For each test case, output a single integer, denoting the minimum possible absolute difference between the satisfactory values of the two types of programs.
Sample Input
2
5
27 46
89 13
55 8
71 86
22 35
3
3 5
4 7
6 2
Sample Output
3
1
题意: 给出t组样例,每组表示有n个学生,每个学生有对应的唱歌满意度和相声满意度,每个学生只能选择其中一种,最终唱歌的满意度为选择了唱歌的最大满意度,最终相声的满意度为选择了相声的最大满意度,求这两个满意度的最小差值。
思路: 先对唱歌满意度由大到小排序,同时用一个数组记录相声满意度(排序后利用二分去找与当前唱歌满意值最接近的相声满意值),从第一个最大的唱歌满意度开始枚举,假设当前他选择唱歌,那么其答案为除本身剩余相声值的最大值,然后依次往后,第二个的最大相声值则要从第一个的相声值和除本身的去选,依次这样模拟,对每次的答案取min即为最终结果,详情看代码和注释。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
struct node {
ll a, b;
}g[N];
ll y[N];
map<ll, int> book;
bool cmp(node p, node q) {
if (p.a == q.a) return p.b < q.b;
else return p.a > q.a;
}
int main() {
int T, n, t;
scanf("%d", &T);
while (T--) {
book.clear();
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%lld%lld", &g[i].a, &g[i].b);
y[i] = g[i].b; // 记录相声值
book[g[i].b]++;
}
sort(y, y + n); // 排序后实现后面的二分查找
sort(g, g + n, cmp);
ll ans = 1e18 + 5;
ll maxn = -1e2;
// 对唱歌的满意值由大到小排序后,每次枚举当前最大唱歌值与剩余最大相声的差值
for (int i = 0; i < n; i++) {
if (maxn >= g[i].a) {
/*
如果当前唱歌的满意值小于当前上面的(一开始假设为唱歌后改为说相声的)最大相声满意值
那么其解一定是最大相声满意值减去当前最大唱歌满意值
*/
ans = min(maxn - g[i].a, ans);
} else {
//否则,则去找与当前最大唱歌值相近的最大相声满意值
/*先找出第一个大于等于当前唱歌值的下标,再枚举其周边相对应下标
注意的是,不能是其左边的相声值,所以判断其是否相等,但相等也有两种情况
就是该值是否有重复,所以加了个map记录该数字出现的次数
由于为了排除使其本身右边的数值,所以对t-2,t-1,t,t+1这四个范围进行枚举,
找出最接近当前唱歌满意值的数字
*/
t = lower_bound(y, y + n, g[i].a) - y; // 查找第一个大于等于当前唱歌满意值的下标
// 枚举t和t+1的情况
if (t < n && (y[t] != g[i].b || book[y[t]] != 1)) {
ans = min(y[t] - g[i].a, ans);
}
if (t + 1 < n && (y[t + 1] != g[i].b || book[y[t + 1]] != 1)) {
ans = min(y[t + 1] - g[i].a, ans);
}
// 枚举t-2和t-1的情况
if (t - 1 >= 0 && (y[t - 1] != g[i].b || book[y[t - 1]] != 1)) {
ans = min(g[i].a - y[t - 1], ans);
}
if (t - 2 >= 0 && (y[t - 2] != g[i].b || book[y[t - 2]] != 1)) {
ans = min(g[i].a - y[t - 2], ans);
}
}
if (g[i].b >= maxn) maxn = g[i].b; // 更新一开始假设为唱歌后改为说相声的最大相声满意值
}
printf("%lld\n", ans);
}
return 0;
}