2016普及赛补充程序3-分析

(郊游活动)有 n 名同学参加学校组织的郊游活动,已知学校给这 n 名同学 的郊游总经费为 A 元,与此同时第 i 位同学自己携带了 Mi 元。为了方便郊 游,活动地点提供 B(≥n)辆自行车供人租用,租用第 j 辆自行车的价格为 Cj 元,每位同学可以使用自己携带的钱或者学校的郊游经费,为了方便账务管 理,每位同学只能为自己租用自行车,且不会借钱给他人,他们想知道最多 有多少位同学能够租用到自行车。(第四、五空 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;

bool check(int nn) {
    int count = 0, i, j;
    i = ①;
    j = 1;
    while (i <= n) {
        if(②)
            count += C[j] - M[i];
        i++;
        j++;
    }
    return ③;
}
    
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) / 2;
        if(④){
            ans = mid;
            l = mid + 1;
        }else
            r = ⑤;
    }
    cout << ans << endl;
    return 0;
}

 

程序分析:

 

#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个人是否都可以租到车 
    int count = 0, i, j;
    /*贪心--让钱最多的那一组人租便宜的那些车
     *这组人钱少的租相对便宜的车,需要使用学校经费最少 
     */ 
    i = n-nn+1; 
    j = 1;
    while (i <= n) { 
        //如果当前学生带钱M[i]小于租这辆车的钱C[j],需要用学校经费 
        if(M[i]<C[j])
            count += C[j] - M[i];
        i++;//当前学生i租到车 
        j++;//当前车j被租出去 
    }
    //学校经费A是否满足这些学生租赁需要的经费
    //满足表示nn个学生可以租到车,不满足表示nn个学生不能租到车
    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);//n个学生按带钱多少从小到大排序 
    sort(C, 1, B);//B辆自行车按租金从小到大排序 
    l = 0;
    r = n;
    while (l <= r) {
        mid = (l + r) / 2;//二分找一半的学生
        //check函数检查mid个学生是否可以租到车 
        if(check(mid)){
            //mid个学生租到车保存到ans变量 
            ans = mid;
            //继续二分找更多的学生 
            l = mid + 1;
        }else
            r = mid - 1;//如果mid学生不能租到车,缩小一半继续查找 
    }
    cout << ans << endl;
    return 0;
}

 

posted @ 2020-09-19 13:22  new-code  阅读(160)  评论(0)    收藏  举报