NOIP 2016 普及组初赛试题 郊游活动 贪心+二分
- 贪心:先选带钱多的学生去租车,先选价格低的车去租。这样才能最大化利用 活动总经费
- 第4个空,if (____) 这个check( )函数对边界判断需要多思考一二,是小于,还是小于等于
// 利用单调性,左边都是满足条件的,求的是尽可能多的边界,所以left是答案
// check(mid)落到符合要求的区间,就更新左边界
// 一种二分模板
// l < r
#include <iostream>
using namespace std;
#define MAXN 1000000
int n, B, A, M[MAXN], C[MAXN], l, r, ans, mid;
bool check(int nn) { //判断nn个人能不能骑上自行车,返回的是nn人能骑上
int count = 0, i, j;
i = n- nn + 1;
j = 1;
while (i <= n) {
if(C[j] > M[i])
count += C[j] - M[i]; //自行车的钱 - 小孩兜里的钱 需要多少资金的支持
i++;
j++;
}
return count <= A; //资金够不够用
}
void sort(int a[], int l, int r) {
int i = l, j = r, x = a[(l + r) / 2], y;
while (i <= j) {
while (a[i] < x) i++;
while (a[j] > x) j--;
if (i <= j) {
y = a[i]; a[i] = a[j]; a[j] = y;
i++; j--;
}
}
if (i < r) sort(a, i, r);
if (l < j) sort(a, l, j);
}
int main() {
int i;
cin >> n >> B >> A;
for (i = 1; i <= n; i++) cin >> M[i];
for (i = 1; i <= B; i++) cin >> C[i];
sort(M, 1, n);
sort(C, 1, B);
l = 0; r = n;
while (l < r) {
mid = (l + r + 1) / 2;
if(check(mid)){ //mid人能不能骑上骑自行车
l = mid;
ans = mid;
}else
r = mid - 1;
}
cout << ans << endl;
return 0;
}
// 题目的二分模板
// l <= r
#include <iostream>
using namespace std;
#define MAXN 1000000
int n, B, A, M[MAXN], C[MAXN], l, r, ans, mid;
bool check(int nn) { //判断nn个人能不能骑上自行车,返回的是nn人能骑上
int count = 0, i, j;
i = n- nn + 1;
j = 1;
while (i <= n) {
if(C[j] > M[i])
count += C[j] - M[i]; //自行车的钱 - 小孩兜里的钱 需要多少资金的支持
i++;
j++;
}
return count <= A; //资金够不够用
}
void sort(int a[], int l, int r) {
int i = l, j = r, x = a[(l + r) / 2], y;
while (i <= j) {
while (a[i] < x) i++;
while (a[j] > x) j--;
if (i <= j) {
y = a[i]; a[i] = a[j]; a[j] = y;
i++; j--;
}
}
if (i < r) sort(a, i, r);
if (l < j) sort(a, l, j);
}
int main() {
int i;
cin >> n >> B >> A;
for (i = 1; i <= n; i++) cin >> M[i];
for (i = 1; i <= B; i++) cin >> C[i];
sort(M, 1, n);
sort(C, 1, B);
l = 0; r = n;
while (l <= r) {
mid = (l + r + 1) / 2;
if(check(mid)){ //mid人能不能骑上骑自行车
l = mid + 1;
ans = mid;
}else
r = mid - 1;
}
cout << ans << endl;
return 0;
}
// 自己重新写了一下
#include <bits/stdc++.h>
using namespace std;
const int N = 10010;
int n, B, A;
int M[N], C[N];
bool check(int nn)
{
int cnt = 0;
int i = n - nn + 1, j = 1;
while (i <= n){
if (C[j] > M[i]) cnt += C[j] - M[i];
i++, j++;
}
return cnt <= A;
}
int main()
{
cin >> n >> B >> A;
for (int i = 1; i <= n; i++) cin >> M[i];
for (int i = 1; i <= n; i++) cin >> C[i];
sort(M + 1, M + 1 + n);
sort(C + 1, C + 1 + n);
int l = 0, r = n, best = 0;
while (l < r){
int mid = (l + r + 1) >> 1;
if (check(mid)){
l = mid;
best = mid;
}
else{
r = mid - 1;
}
}
cout << best << '\n';
return 0;
}