codeforces949D Curfew

190 篇文章 2 订阅
24 篇文章 0 订阅

题面

题意

一条直线上有n个寝室,每个寝室中有 a i a_i ai个人,现在有两个宿管分别从左右两边向中间走,每个单位的时间查一个寝室,若人数不足b个,则会记录,最中间的寝室归左边的宿管,现在每个人每个单位的时间可以跑d个寝室,则两个宿管记录下的寝室数量的较大值的最小值是多少。

做法

这题有一个很棒的贪心,可以从左向右扫(直到中间),如果可以到达这个寝室的人数(在宿管来之前)大于等于b,就让这些人过来,反之不过来且答案++,然后再倒着做一遍相同的事,两个答案中的较大值即为答案。
可以发现,中间的人向左走似乎会让右边的答案不优,但是可以发现,中间的人向左走的前提是左边的人数不够,也就是右边的人数有多,因此答案不会变劣。

代码

#include<bits/stdc++.h>
#define N 100100
using namespace std;

int n,d,b,num[N],A,B,sum;

int main()
{
    int i,j;
    cin>>n>>d>>b;
    for(i=1;i<=n;i++) scanf("%d",&num[i]);
    for(i=j=1;i<=(n+1)/2;i++)
    {
		for(;j<=min(i*(d+1),n);j++) sum+=num[j];
		if(sum<b) A++;
		else sum-=b;
    }
    reverse(num+1,num+n+1);
    sum=0;
    for(i=j=1;i<=n/2;i++)
    {
		for(;j<=min(i*(d+1),n);j++) sum+=num[j];
		if(sum<b) B++;
		else sum-=b;
    }
    cout<<max(A,B);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值