当前位置: 首页 > 工具软件 > Popcorn Time > 使用案例 >

2020-10-08 组队赛补题 M - Maratona Brasileira de Popcorn Gym - 102346M

尉迟越
2023-12-01

Problem M
Maratona Brasileira de Popcorn
The “Maratona Brasileira de Popcorn” is a competition that takes place annually to find out which
team is the most organized, prepared and well-trained in the art of eating popcorn. It is organized by
Brazilian Society of Popcorn Eaters (SBCp, its acronym in Portuguese), which periodically meets to
discuss the rules and format of the competition.
The competition consists of N popcorn bags placed side by side, where each bag has an arbitrary
amount of popcorn. For added fun, the competition takes place in teams, each made up of C competitors.
Since the “Maratona Brasileira de Popcorn” is a serious event that values, above all, the health
of the competitors, the medical commission has imposed that each competitor may eat a maximum of
T popcorn per second to avoid possible sickness.
At its last meeting, SBCp defined two new rules for the 2019 edition:
– Each team competitor must eat a contiguous sequence of popcorn bags. It is perfectly valid that
a competitor does not eat any popcorn.
– All popcorn in the same bag must be eaten by a single competitor.
The goal of the competition is to eat all the popcorn in the shortest possible time as the C
competitors can eat in parallel and they will abide by all rules imposed by the SBCp.
Input
The first line of input contains three integer numbers N, C y T (1 ≤ N ≤ 105
, 1 ≤ C ≤ 105 and
1 ≤ T ≤ 50), representing the number of popcorn bags in the competition, the number of competitors
in the team, and the maximum amount of popcorn per second a competitor can eat. The second line
contains N integers Pi (1 ≤ Pi ≤ 104
), representing the amount of popcorn on each of the N popcorn
bags.
Output
Your program must output a single line, containing an integer number, representing The minimum
amount of seconds it takes for the team to eat all the popcorn if they organize themselves as best
possible.
Input example 1
5 3 4
5 8 3 10 7
Output example 1
4
Input example 2
3 2 1
1 5 1
Output example 2
6
Input example 3
3 2 1
1 1 5
Output example 3
5

题意:有n桶爆米花,c个人,没人每秒最多吃t个,一桶爆米花只能被一个人吃,且一个人吃完当前桶内爆米花后只能去相邻的桶内吃,问c个人最少用几秒可以吃完
思路:用二分查找,找出最短时间

tips:一些求最短时间的问题一般都可以用二分的方法枚举找最小值

  • 含有代码块的列表项:
    #include
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+10;
    typedef long long ll;
    ll a[maxn];
    ll n, c, t;
    int main()
    {
    //使用二分方法,进行枚举,找最小值
    cin>>n>>c>>t;
    ll left = 1, right = 0, mid, ans = 0x3f3f3f3f;//left表示每个人最少吃几秒,left表示每个人最多吃几秒,ans表示最终答案
    for(int i = 1; i<=n; i++)
    {
    scanf("%lld",&a[i]);
    right += a[i];
    }
    //只要人数大于等于一,每次最多能吃的个数大于等于一,每个人最多吃a[i]的和秒必能吃完,即最大值;
    while(left <= right)//二分
    {
    mid = (left+right)>>1;
    ll eat = t*mid;//eat表示一个人mid秒可以吃几个;
    ll now = 0;//now表示个人当前所吃的个数;
    ll cnt = 1;//当前人数
    for(int i = 1; i<=n; i++)
    {
    if(a[i]>eat)//如果有一个a[i]大于eat,由于一桶爆米花只能同时一个人吃,所以mid秒不可能吃完;、
    {
    cnt = 0x3f3f3f3f;
    break;//所以结束循环
    }
    now+=a[i];//如果a[i]<=eat.更新当前now的值
    if(now > eat)//当前的人数不够,吃不完,所以人数加一;
    {
    cnt++;
    now = a[i];//更新当前个人所吃的爆米花数量;
    }
    }
    if(cnt > c)//如果吃完后所需要的人数大于题目给出的人数,则增加mid值,去右边查找;
    {
    left = mid+1;
    }
    else//否则说明当前时间内可以吃完爆米花,更新ans,并且去左区间寻找更短的时间;
    {
    ans = mid;
    right = mid-1;
    }
    }
    cout<<ans<<endl;
    return 0;
    }
 类似资料: