Codeforces Round 881 (Div. 3)20230621 - 个人部分AC题解(Python)

太久没有刷算法题了,前四道题居然直接干到50分钟去了... em.... 得好好练习了.....

题目不全,后续再补。。。

c878e1c8078d44e5a3aa16fcd8d5dd7e.png

20d3127e43fc4771886c711b75ccc775.png

简述:给一个数组,自由将数组分成n个子数组,每个子数组都会最大最小值,分别将其差累加后,只要满足累加值最大化就好了。

思路:排个序,只要当前ls中还有数据且长度不为1,就从最左边和最右边各取一个相加,类似于双端队列,pyyyds~。

def solve():
    n = int(input())
    ls = list(map(int,input().split()))
    ls.sort(reverse = True)
    res = 0
    while ls:
        if len(ls) == 1:
            break
        max_ = ls.pop(0)
        min_ = ls.pop(-1)
        res += max_ - min_
    print(res)

def main():
    t = int(input())
    while t:
        solve()
        t -= 1
main()

 67d4235d94664248aba2483ac2de9f30.png303c355a22c54269ac08792ab7885367.png

简述:给一个数组,你可以有若干次或者零次操作,在这每次操作中,你可以任选一个区间(l,r)(1<=l<=r<=n),使得数组中的这个区间内所有的元素都乘-1,最后问求最少操作次数以及这个数组的最大累积和。

思路:这个数组最大累积和必然是这个数组中的所有元素的绝对值之和。而目标是使用尽可能少的操作数让数组中的多个负数一次性变成正数,即尽可能的让每个[l,r]的覆盖范围更大。这里用到了双指针,左指针从左往右找到数组中第一个小于0的数,对于确定的左指针 l ,更新最大的右指针r,使得数组[l,r]内都是小于等于0的数,以便一次性解决,直到 r 无法继续右移,则 l 的新位置更新为r+1,此时只需线性复杂度就可以找到最少的操作次数了。

def solve():
    n = int(input())
    ls = list(map(int,input().split()))
    sums = 0
    for l in ls:
        sums += abs(l)
    l, cnt = 0, 0
    while l < n:
        if ls[l] < 0:
            cnt += 1
            r = l
            while r < n - 1 and ls[r + 1] <= 0: r += 1
            l = r + 1
        else:
            l += 1
    print(sums,cnt)
def main():
    t = int(input())
    while t:
        solve()
        t -= 1
main()

 c43077233aca4190a9a70d5bf2ec164a.png

406d699be0ea443aa07b8bd453682864.png

简述:有一颗无穷大的树,给一个结点n,问从结点n到根节点(结点1)路径上的结点之和为多少?

思路:dfs写就可以了,主要还是公式,编号 i 结点的两个孩子结点编号分别为 2i 和 2i + 1,定义一个dfs状态,参数表示当前结点编号,每次都往父节点递归即可,边界条件为遇到根节点时返回,每次递归都将结点值记录起来就是答案了。

res = 0
def dfs(ver):
    global res
    res += ver
    if ver == 1:
        return
    if ver % 2 == 0:
        dfs(ver // 2)
    else:
        dfs((ver - 1) // 2)
 
def main():
    global res
    t = int(input())
    for _ in range(t):
        n = int(input())
        dfs(n)
        print(res)
        res = 0
main()

代码为比赛代码, 文章写得粗糙,题目暂不完整,后续补全和优化,请海涵!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值