2 条题解
-
0
这道题不难想到,最终的答案肯定是一个区间和,由于我们要在保证软件ACM成员都开心的情况的条件下,保证自己的最多,那既然最多,其他成员的美味值就恰好为v,或者第一次大于v的时候就停止分,这样确保lfq分到的是最多的,我们可以分为三个区间,lfq分在[L,R]中的蛋糕,那剩余的[1,L-1],[R+1,n]的值的和要>=m,于是就有下面的代码
#include <bits/stdc++.h>
using namespace std;
long long a[200100], l[200100], r[200100], he[200100];
int main()
{
int t;
scanf("%d", &t);
for (int i = 1; i <= t; i++)
{
int n, m, v;
scanf("%d%d%d", &n, &m, &v);
for (int i = 1; i <= n; i++)
{
scanf("%lld", &a[i]);
}
l[0] = 0;
long long sum = 0;
for (int i = 1; i <= n; i++)//该代码是求从1到n,满足美味值大于v的人数,例如,此时l[i]的值为3,那就代表从1到i有3个人满足分到蛋糕的美味值大于v
{
l[i] = l[i - 1];
sum += a[i];
if (sum >= v)
{
l[i]++;
sum = 0;
}
}
sum = 0;
r[n + 1] = 0;
for (int i = n; i >= 1; i--)//与l代表的意义一样,之所以从n到1,是因为最终的答案肯定是一个区间和,假如是[L,R],那整个n就被分为三部分[1,L-1],[L,R],[R+1,n],由于不清楚R+1,所以我们没法从R+1到n,但是我们可以从n到R+1,那为什么不直接用之前的l数组呢?那是因为他们两个中间隔着[L,R],而l数组记录了[L,R],会对之后的数据产生影响
{
r[i] = r[i + 1];
sum += a[i];
if (sum >= v)
{
r[i]++;
sum = 0;
}
}
he[0] = 0;//前缀和,用于计算最终答案。
for (int i = 1; i <= n; i++)
{
he[i] = he[i - 1] + a[i];
}
long long ans = -1;
if (l[n] >= m)//因为从1到n,美味值至少为v的人数达到m,所以最终答案的值不为-1。
{
ans = 0;
}
int r1 = 1;//开始遍历区间[L,R],这种方法叫双指针,可以去学一学,先固定右端点r1,移动左端点l1,当左端点大于右端点时,我们把此时的右端点移到左端点。
int l1 = 1;
for (l1 = 1; l1 <= n; l1++)
{
if (l1 > r1)
{
r1 = l1;
}
while (l[l1 - 1] + r[r1 + 1] >= m && r1 <= n)//前提条件成立,开始求最大值(通过移动右端点),直到前提条件不符合。
{
ans = max(ans, he[r1] - he[l1 - 1]);
r1++;
}
}
printf("%lld\n", ans);
}
return 0;
}
信息
- ID
- 1188
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- 递交数
- 19
- 已通过
- 2
- 上传者