【AcWing蓝桥杯集训·每日一题】【差分】【3729. 改变数组元素】Python解.差分知识点学习~

【Week 1_2.14】差分

目录

一、一维数组差分例题及解题思路

二、AcWing 3729. 改变数组元素(每日一题)

1.题目描述

2.代码实现

3.简化版代码


本题考察一维数组差分。

这道题整体思路还是比较清晰的,

先分享一下一维数组差分的常规解题思路。

掌握例题解题思路,这道题就迎刃而解啦~

一、一维数组差分例题及解题思路

# 一维数组差分
# https://www.bilibili.com/video/BV1pi4y1j7si?p=2&vd_source=95585215c756caf0d30065463e625a78
# 如果基础知识不太熟悉推荐看这位up主的视频讲解,个人觉得讲得非常细致容易理解
"""
重点1:差分标记:
[L, R] + v <==> d[L] + v, d[R + 1] - v
"""

# 例题:
# 1.给定一维数组:arr = [1,3,7,5,2]
# 2.给m个操作 [L, R] + v  如 [2, 4] + 5  [1, 3] + 2  [0, 2] - 3
# 3.一个询问:求m个操作后该数组的最后结果arr

'''
重点2:做法思路
1.求出arr的差分数组d: d = [1,2,4,-2,-3]  (后一个元素减前一个元素:d[i] = arr[i] - arr[i - 1])
2.利用差分标记计算:
    [2, 4] + 5 ==> d[2] + 5  (d[5]越界,并不需要再减去了)
    [1, 3] + 2 ==> d[1] + 2, d[4] - 2
    [0, 2] - 3 ==> d[0] - 3, d[3] + 3
    得d = [-2,4,9,1,-5]
3.通过求差分数组的前缀和,可以得到该差分数组的原数组
    sum_d = [-2,2,11,12,7] (既是前缀和,也是原数组,也就是最后的结果)
'''

'''
调试用例:
3
2 4 5
1 3 2
0 2 -3
'''
arr = [1, 3, 7, 5, 2]
d = [arr[0]]  # 差分数组d
for i in range(1, len(arr)):
    d.append(arr[i] - arr[i - 1])


# 差分标记
def add(l, r, v):
    d[l] += v
    if r + 1 < len(arr):
        d[r + 1] -= v


m = eval(input())
for i in range(m):
    L, R, V = map(int, input().split())
    add(L, R, V)

# 差分数组的前缀和
sum_d = [d[0]]
for i in range(len(d) - 1):
    sum_d.append(sum_d[i] + d[i + 1])
print(sum_d)

 

二、AcWing 3729. 改变数组元素(每日一题)

1.题目描述

【AcWing蓝桥杯集训·每日一题】【差分】【3729. 改变数组元素】Python解.差分知识点学习~_第1张图片

2.代码实现

T = eval(input())
for _ in range(T):
    n = eval(input())  # 6
    V = [0] * (n + 1)
    a = list(map(int, input().split()))  # 0 3 0 0 1 3
    for i in range(n):
        if a[i]:
            if a[i] > i + 1:
                a[i] = i + 1
            # [i - (a[i] - 1), i] + 1 --> d[i - (a[i] - 1)] + 1 ,d[i + 1] - 1
            V[i - (a[i] - 1)] += 1
            V[i + 1] -= 1
    pre = [V[0]]
    for j in range(n - 1):
        pre.append(pre[j] + V[j + 1])
    for j in range(n):
        if pre[j] > 1:
            pre[j] = 1
    print(' '.join(map(str, pre)))

3.简化版代码

简化版代码来源:可爱抱抱呀

for i in range(int(input())):
    n, a = int(input()), list(map(int, input().split()))
    arr = [0] * (n + 5)
    for j in range(n):
        arr[max(0, j - a[j] + 1)] += 1
        arr[j + 1] -= 1
    for j in range(1, n):
        arr[j] += arr[j - 1]
    for b in arr[:n]:
        print(1 if b else 0, end=' ')
    print()
关于 1 if b else 0 做以下补充:
  • Python中没有三元运算符,但是有替代方案: x if y else z
  • 解释:先计算y,如果为True,则返回x,否则返回z。
  • 注意:x、y、z 都可为表达式
  • 举例:
a, b, c = 1, 2, 3
if a > b:
    c = a
else:
    c = b

可简化为

c = a if a > b else b
  •  在本题中,1 if b else 0 即:

        如果b!=0,输出1;如果b==0,输出0


如有不足或不解之处欢迎留言指正哈。

如有帮助可以点赞收藏嘛,感谢~

你可能感兴趣的:(python,蓝桥杯,蓝桥杯,学习,算法,python)