I.Algorithm Choosing Mushrooms

链接:https://ac.nowcoder.com/acm/contest/908/I

题意:

Baby bear and his good friends are very fond of mushrooms. On this day, they go to 402 mushroom field together. Kuangyeye, the owner of the mushroom field, is very happy to see the children. He is going to give the children some mushrooms, so he takes them to a warehouse.

In the warehouse, there are N baskets in a row, numbered from 1 to N, with some mushrooms in each basket. Baby bear and his friends can take several baskets of mushrooms, but Kuangyeye has several requirements:

·Kuangyeye likes to be neat and tidy. He asks the children to take away only the consecutively numbered baskets when they take the mushrooms. This means that if the children choose the 4th, 5th and 6th baskets of mushrooms, they can't choose the 9th basket unless they also choose the 7th and 8th baskets.

·Kuangyeye likes all of them, so he asks each child to get the same number of mushrooms. This means that the total number of mushrooms the children take away must be P = k * M, where k is an integer and M is the total number of children.

·Kuangyeye made a record of the number of mushrooms in each basket. He asks the children not to put some mushrooms in other baskets or throw them away. This means that when the children take a basket of mushrooms, they must take away all the mushrooms in the basket.

Now given the number of mushrooms in a row of N baskets, please answer:

1. The maximum number of mushrooms that baby bear and his friends can take away.

2. The maximum number of baskets that baby bear and his friends can take away.

Please note that the answers to questions 1 and 2 May not come from the same situation!!!

思路:

用一个二维数组记录原数组的前缀和数组modm的值。

如果sum[j]%m == sum[i]%m 则(sum[j]-sum[i])%m == 0说明j-(i-1)篮子里的蘑菇是m的倍数。(sum为前缀和数组)

找到%m的每个余数去最左和最右的两个位置。%m为0时只用取最右的。

代码:

#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long LL;
const int MAXN = 2e6 + 10;
const int MOD = 1e9 + 7;
int n, m, k, t;
 
LL fsum[MAXN];
int Po[MAXN][2];
 
int main()
{
    memset(Po, -1, sizeof(Po));
    scanf("%d%d", &n ,&m);
    LL sum = 0;
    for (int i = 1;i <= n;i++)
    {
        scanf("%lld", &fsum[i]);
        fsum[i] += fsum[i-1];
    }
    for (int i = 1;i <= n;i++)
    {
        int lef = fsum[i] % m;
        if (lef == 0)
        {
            Po[lef][0] = i;
            continue;
        }
        if (Po[lef][0] == -1)
            Po[lef][0] = i;
        else
            Po[lef][1] = i;
    }
    LL res1 = 0;
    int res2 = 0;
    for (int i = 1;i <= m;i++)
    {
        if (Po[i][1] == -1)
            continue;
        res1 = max(res1, fsum[Po[i][1]]-fsum[Po[i][0]]);
        res2 = max(res2, Po[i][1]-Po[i][0]);
    }
    if (Po[0][0] != -1)
    {
        res1 = max(res1, fsum[Po[0][0]]);
        res2 = max(res2, Po[0][0]);
    }
 
    printf("%lld %d", res1, res2);
 
    return 0;
}

  

转载于:https://www.cnblogs.com/YDDDD/p/10960397.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值