C++,codeforces,158B,B. Taxi

/*
codeforces,158B,B. Taxi
将n组学生送到目的地,每组学生包含1~4名学生
每辆车最多载4名学生,每个组的所有学生必须乘坐同一辆车,一辆车可以载多组的学生
最少需要多少辆车
输入
第一行: 一个数字,n
第二行: n个空格隔开的数字,表示第i组学生的人数
*/

/*
*/
#include <iostream>
#include <vector>
#define FULL_SEATS 4
int main(){
    int n;std::cin>>n;
    int ans = 0;
    std::vector<int> counts(FULL_SEATS,0);//count of 1 2 3
    //counts用于记录人数为1,2,3的组分别有几个,用counts[1],counts[2],counts[3]记录

    for(int i = 0;i<n;++i){
        int x;std::cin>>x;
        if(x==FULL_SEATS){
            //如果该组学生能坐满一辆空车,车数+1
            ans++;
            continue;
        }else{
            //如果该组学生不能坐满空车
            if(counts[FULL_SEATS-x]>0){
                //如果有互补的组,能凑满一辆车
                --counts[FULL_SEATS-x];//互补的组数-1
                ans++;//最终车数+1
                continue;
            }else{
                //如果没有互补的组,该人数的组数+1
                ++counts[x];
            }
        }    
    }
    int end = FULL_SEATS-1,head = 1;
    //end记录当前剩余组中,人数最大的组的人数
    //head记录当前剩余组中,人数最小的组的人数
    while(end>=head){
        while(counts[end]==0 && end>=head)--end;
        while(counts[head]==0 && head<=end)++head;
        if(end<head)break;
        // while(counts[head]==0)++head;
        int i = end;
        int emptySeat = FULL_SEATS;
        //一次装一辆车
        while(emptySeat>=head){
            //尽量装人数最多的组,直到人数最少的组都装不下为止

            //保持i为当前能装下的组中最大的人数
            while(counts[i]==0)--i;//counts[head]!=0,i>=head
            int groups = std::min(emptySeat/i,counts[i]);
            emptySeat-=groups*i;
            counts[i]-=groups;
            if(emptySeat<head){
                //人数最小的组都装不下
                break;
            }else{
                //人数正好为剩余的空位的组
                i = emptySeat;
            }
            while(counts[head]==0)++head;
        }
        ++ans;
    }
    std::cout<<ans;
}

posted @ 2025-03-07 20:09  Kazuma_124  阅读(12)  评论(0)    收藏  举报