题目大意: 有n个选手每个选手有两种能力值,现在需要第一种能力值的选手X个,第二种能力值的选手Y个。问所有选手中能力值最小的最大是多少。
解题思路: 正向求解完全没有思路,但是我们可以很容易的判断给定一个能力值x,是否存在满足情况的解。于是二分答案。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int MAXN = 500005; 5 6 int n, X, Y; 7 int s0[MAXN], s1[MAXN]; 8 9 int check(int x) 10 { 11 int cnt0 = 0, cnt1 = 0, cnt01 = 0; 12 for (int i = 0; i < n; ++i) 13 { 14 if (s0[i] >= x && s1[i] >= x) 15 { 16 ++cnt01; 17 } 18 if (s0[i] >= x) 19 { 20 ++cnt0; 21 } 22 if (s1[i] >= x) 23 { 24 ++cnt1; 25 } 26 } 27 // printf("cnt0 = %d cnt1 = %d cnt01= %d ", cnt0, cnt1, cnt01); 28 // printf("X = %d Y = %d ", X, Y); 29 if (cnt0>=X && cnt1>=Y && cnt0 + cnt1 - cnt01 >= X+Y) 30 { 31 return 1; 32 } 33 return 0; 34 } 35 36 void solve() 37 { 38 int l = 1; 39 int r = 10000; 40 while (l <= r) 41 { 42 // printf("l = %d r = %d ", l, r); 43 int mid = (l + r)/ 2; 44 // printf("mid = %d check = %d ", mid, check(mid)); 45 if (check(mid)) 46 { 47 l = mid + 1; 48 } 49 else 50 { 51 r = mid - 1; 52 } 53 } 54 printf("%d ", l - 1); 55 } 56 57 int main() 58 { 59 #ifndef ONLINE_JUDGE 60 freopen("test.txt", "r", stdin); 61 #endif // ONLINE_JUDGE 62 int Case; 63 scanf("%d", &Case); 64 while (Case--) 65 { 66 scanf("%d%d%d", &n, &X, &Y); 67 // printf("X = %d Y = %d ", X, Y); 68 for (int i = 0; i < n; ++i) 69 { 70 scanf("%d%d", &s0[i], &s1[i]); 71 } 72 solve(); 73 } 74 return 0; 75 }