题目链接: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