Codeforces 158B Taxi 题解

本文解析了一道Codeforces上的经典题目,讲述了如何计算最少数量的出租车来运送不同规模的小团队到达目的地的方法。重点在于考虑各种团队规模的组合方式,并通过有效的算法实现最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:

http://codeforces.com/problemset/problem/158/B

Description

After the lessons n groups of schoolchildren went outside and decided to visit Polycarpus to celebrate his birthday. We know that the i-th group consists of si friends (1 ≤ si ≤ 4), and they want to go to Polycarpus together. They decided to get there by taxi. Each car can carry at most four passengers. What minimum number of cars will the children need if all members of each group should ride in the same taxi (but one taxi can take more than one group)?

Input

The first line contains integer n (1 ≤ n ≤ 10^5) — the number of groups of schoolchildren. The second line contains a sequence of integers s1, s2, …, sn (1 ≤ si ≤ 4). The integers are separated by a space, si is the number of children in the i-th group.

Output

Print the single number — the minimum number of taxis necessary to drive all children to Polycarpus.

题目大意:

有n伙小孩,每伙小孩有1~4人,大家拼出租车,出租车有4个座位,每伙小孩可以拼车,同一伙小孩不能分开,问最小要几辆出租车。

思路:

4人的团伙肯定要先坐车,1人团伙与3人团伙拼车,2个2人团伙也可以拼车,剩下的就可以另作打算,较为简单了。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
int n,a[5],ans=0,k;
int main()
{
    memset(a,0,sizeof(a));
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&k);
        a[k]++;
    } 
    ans+=a[4]+a[2]/2;
    a[2]%=2;
    k=min(a[1],a[3]);
    ans+=k;
    a[1]-=k;
    a[3]-=k;
    if(a[3]!=0) ans+=a[3];
    if(a[1]!=0)
    {
        ans+=a[1]/4;
        a[1]%=4;
    }
    k=a[1]+a[2]*2;
    if(k<=4&&k!=0) ans++;
    else if(k!=0) ans+=2;
    cout<<ans<<endl;
    return 0;
}

相关链接:

Codeforces 题解小全:
https://blog.youkuaiyun.com/ZJ_MRZ/article/details/81530091

Codeforces 1016A Death Note 题解:
https://blog.youkuaiyun.com/ZJ_MRZ/article/details/81474520

Codeforces 1017A The Rank 题解:
https://blog.youkuaiyun.com/ZJ_MRZ/article/details/81529980

Codeforces 1017B The Bits 题解:
https://blog.youkuaiyun.com/ZJ_MRZ/article/details/81530892

转载于:https://www.cnblogs.com/zj-mrz/p/10122451.html

### 关于Codeforces上的位运算题目解答 #### 逻辑运算的应用 在处理一系列整数时,为了找到这些数字共同拥有的二进制特征,可以利用`&`(按位)运算符。因为当两个对应的二进制位都为1时,结果才为1;只要有一个不为1,则结果就变为0。这意味着,在一组数值中通过连续执行按位操作能够筛选出所有成员共有的二进制模式[^1]。 ```cpp #include <cstdio> using namespace std; int main() { int t; scanf("%d", &t); while(t--) { int n, x; scanf("%d%d", &n, &x); int ans = x; for(int i = 1; i < n; i++) { scanf("%d", &x); ans &= x; // 对序列中的每一个数做按位 } printf("%d\n", ans); // 输出最终的结果 } return 0; } ``` 这段代码展示了如何遍历输入的一系列整数并应用按位(`&`)来找出它们共享的最低限度公共设置位。 #### 处理区间内最小值的最大化问题 对于特定范围内的某些优化挑战,比如最大化某个区间的最小可能值,可以通过巧妙地调整循环条件以及使用特殊的增量表达式(~i&-~i),从而有效地减少不必要的迭代次数[^2]。 ```cpp for (long long i = l; i <= r; i += ~i&-~i) { ans = i; } cout << ans << endl; ``` 此片段尝试在一个指定范围内寻找满足一定条件下最大的起点位置。 #### 字符串匹配验证 针对包含不同类型的标记字符(如'Q'代表提问,'A'代表回答)的任务,可通过简单的计数器机制确保每种事件的发生频率相匹配,以此判断是否存在未解决问题实例[^3]。 ```cpp // 假设已经读取到整个字符串s bool isValid(const string& s){ int questionCount = 0; for(char c : s){ if(c == 'Q') ++questionCount; else if(c == 'A'){ if(questionCount > 0)--questionCount; else return false; } } return questionCount==0; } ``` 上述伪码提供了一个简易的方法去检验给定字符串里是否有足够的答案对应每个提出的问题。 #### 差异求解策略 面对需要构建新数组使得其元素之差等于已知量的情况,考虑采用分步构造法,并借助中间变量辅助完成目标设定下的最优路径规划[^4]。 ```cpp if(u > v || (v-u)%2!=0){printf("-1\n");return 0;} if(u==0&&v==0){printf("0\n");return 0;} if(u==v){printf("1\n");printf("%lld\n",u);return 0;} w=(v-u)/2;if((u&w)==0){ printf("2\n"); printf("%lld %lld\n",w,u^w); }else{ printf("3\n"); printf("%lld %lld %lld\n",u,w,w); } ``` 这里展示的是根据不同情况分别采取最短步骤达到预期效果的过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值