完善程序: (郊游活动)有 n 名同学参加学校组织的郊游活动,

已知学校给这 n 名同学 的郊游总经费为 A 元,

与此同时第 i 位同学自己携带了 Mi 元。

为了方便郊游,活动地点提供 B(≥n)辆自行车供人租用,



每位同学可以使用自己携带的钱或者学校的郊游经费,



为了方便账务管理,每位同学只能为自己租用自行车,

且不会借钱给他人,他们想知道最多有多少位同学能够租用到自行车。



(第四、五空 2.5 分,其余 3 分)

本题采用二分法。

对于区间[l, r],

我们取中间点 mid 并判断租用到自行车的人数能否达到 mid。

判断的过程是利用贪心算法实现的。


#include <iostream>

using namespace std;

#define MAXN 1000000


int n, B, A, M[MAXN], C[MAXN], l, r, ans, mid;


//我们取中间点 mid 并判断租用到自行车的人数能否达到 mid。

//判断nn人能不能都租到车子

bool check(int nn)

{

int count = 0, i, j;

i = ①;//i=n-nn+1; [0,mid]

j = 1;

while (i <= n)

{

//与此同时第 i 位同学自己携带了 Mi 元。

//count就学校出的钱,如果自己带的钱够租,尽量不要让学校出钱

//如果自己带的钱不够,让学校负担 C[j] - M[i]的钱

if(②)// M[i]<=C[j]

count += C[j] - M[i];

//还需要多少钱才能租到mid辆的自行车

i++;

j++;

}

return ③;//cout<=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( void )

{

int i;


//已知学校给这 n名同学的郊游总经费为 A 元,

//为了方便郊游,活动地点提供 B(≥n)辆自行车供人租用,

cin >> n >> B >> A;


//与此同时第 i 位同学自己携带了 Mi 元。

for (i = 1; i <= n; i++)

cin >> M[i];


//租用第 i 辆自行车的价格为 C[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) / 2;

if( ④) //check(mid)

//mid个人可以租到自行车

{

ans = mid;

l = mid + 1;

}else

r = ⑤;//mid-1

}


//最多有多少位同学能够租用到自行车。

cout << ans << endl;


return 0;

}


1.正确答案: n-nn+1

2.正确答案: M[i]<C[j] / M[i]<=C[j]

3.正确答案: count<=A

4.正确答案: check(mid)

5.正确答案: mid-1