不同领域的人搭车

题目链接:http://www.bjfuacm.com/contest/115/problem/563/

 

                                                           搭乘出租车

                            发布时间: 2018年4月24日 15:19   最后更新: 2018年4月24日 15:37   时间限制: 1000ms   内存限制: 128M

今天是小A的生日,小A在家里举行了一次生日宴会,并邀请了他的朋友来参加。小A的交友很广,所以小A在n个领域都有朋友(律师朋友,医生朋友等等...)

每个领域的朋友为个数si(1<=si<=4)。他们都一同乘坐出租车来到小A的聚会。但是,每辆出租车最多只能容得下四位乘客,并且相同领域的朋友还必须得坐同一辆出租车,那么最少需要搭乘多少辆出租车呢?(同一辆出租车是可以搭乘多个领域的朋友的)

输入包含多组。输入第一行为一个n(1<=n<=10^5),代表有n个领域的朋友来参加小A的生日宴会。第二行包含n个数,s1,s2,...,sn(1<=si<=4),si代表第i个领域的朋友个数。

输出最少需要搭乘的出租车数量。

5
1 2 4 3 3
4
8
2 3 4 4 2 1 3 1
5

对于第一组样例的解释:

有5个领域的朋友,分别有1,2,4,3,3个人。这样的搭乘方案:第一辆出租车搭乘第一个领域和第二个领域的朋友(1+2<4),第二辆出租车搭乘第三个领域的朋友,第三辆,第四辆分别搭乘另外两个领域的朋友。这样需要的出租车数量最少。

解题思路:

由于每个领域的人数很少,只有1~4个,所以可以利用这个点,运用类似于map的形式,对相同数量的不同的领域进行统一操作。

#include<cstdio>
#include<cstring>
#include<cmath>
#include <algorithm>
#include<iostream>
using namespace std;

int main()
{
    int n;
    while (scanf("%d", &n) != EOF)
    {
        int flag[5], i, sum = 0;
        memset(flag, 0, sizeof(flag));
        for (i = 0; i<n; i++)
        {
            int p;
            scanf("%d", &p);
            flag[p]++;//分别标记人数为1,2,3,4的种数 
        }
        sum += flag[4];
        int n2 = min(flag[1], flag[3]);
        sum += n2;//把人数为1的领域和人数为3的领域凑在一块 
        flag[1] -= n2;
        flag[3] -= n2;
        sum += flag[2] / 2;//把人数为2的领域凑在一块 
        flag[2] %= 2;
        sum += flag[3];//考虑如果人数为3的领域多的情况
        if (flag[2]) //如果还有一类人数为2的领域的朋友没有上车 
        {
            sum++;
            flag[1] -= 2;          //如果人数为1的领域还存在,就与人数为2的领域搭车,若flag[1]=0,人数为2的领域就自己搭车,flag[1]继续-2,并不影响判断
        }
        if (flag[1]>0)
            sum += ceil(flag[1] * 1.0 / 4);//向上取整函数ceil,头文件cmath 
        printf("%d\n", sum);
    }
    return 0;
}

2018-04-25

猜你喜欢

转载自www.cnblogs.com/00isok/p/8946686.html
今日推荐