2021牛客寒假算法基础集训营5 - D石子游戏

前言:哎,这场打的就很nanshou,开局a出俩题,剩下的数学题兴趣就直接无了,结果俩小时直接结束战斗。

结束之后看了一下题解,感觉D题讲的有点麻烦,这边讲一下一种更低效率不过更加直观的做法。如果有看不懂题解的朋友可以尝试一下我的理解。

正文开始#

没看过题目的可以去牛客先看一下。我这里自己出一组数据。
1
5 2
3 3 2 0 2
这里介绍一个算法,差分算法,至于为什么想到的,只能说看到这题就本能的就想到这个算法。
我们对数据进行差分(就是前一个数减后一个数)。得到差分数组cut。
0 1 2 -2
然后我们从左到右推,每次遇到一个数 cut[i] 为正就让cut [ i+k ]加上cut [ i ],cut [i] = 0。注意这里的i+k必须小于等于n(这里是5)。至于为什么后面解释。
然后变成了
0 0 0 -1(2)(最后一个2是前面推来的,在位置n上,我们不需要这个数)
然后从右往左,每次遇到cut [ i ]为负数就让cut [ i - k ] += cut [ i ],cut [ i ] = 0。注意i+k>=0。
然后变成
(-1) 0 0 0 0 (2)
这里面的位置为1到4都是0,所以可以得出结果。

然后解释一下我们为什么做这种操作,我下面列一些变化过程。
3 3 2 0 2 cut:0 1 2 -2
3 3 3 1 2 cut:0 0 2 -1
3 3 3 3 4 cut:0 0 0 -1 (2)
3 3 4 4 4 cut:0 -1 0 0 (2)
4 4 4 4 4 cut:(-1) 0 0 0 0 (2)
懂了吧?因为一次操作的区间为k,所以差分数组会变化的只有i和i+k或i和i-k。
假如i+k>n或者i-k<0,则是不可能的,我们也举个例子。
k=2,3 4 4 4 4 , cut:-1 0 0 0
我们就无法把这个-1给清除掉,因为这涉及数组外的数了。

下面给出代码,速度还有很大的空间可以优化,但是没必要

//
// Created by acer on 2021/2/21.
//

#include <bits/stdc++.h>

using namespace std;
#define int long long
const int maxn = 2e5 + 10;
int num[maxn];
int cut[maxn];

signed main() {
   
    int</
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值