AtCoder abc 136

文章介绍了如何使用贪心方法解决两个问题:一是寻找字符串中连续的RR...RLL...L的循环节,并调整边界以保持奇偶性;二是处理一个整数序列,通过加一减一操作保持总和不变,通过查找符合条件的因子并调整数组来满足给定条件。
摘要由CSDN通过智能技术生成

C
从后向前贪心
D
寻找规律
推一下可以发现连续的RR…RLL…L可以作为一个独立的循环节
最后这个循环节内的数字集中在RL的交界处
再处理一下奇偶性就好

# -*- coding: utf-8 -*-
# @time     : 2023/6/2 13:30
# @author   : yhdu@tongwoo.cn
# @desc     :
# @file     : atcoder.py
# @software : PyCharm
import bisect
import copy
import sys
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(100010)


def main():
    items = sys.version.split()
    if items[0] == '3.10.6':
        fp = open("in.txt")
    else:
        fp = sys.stdin
    s = fp.readline().strip()
    n = len(s)
    rl, ll = [], []
    i = 0
    while i < n:
        bi = i
        while i < n and s[i] == 'R':
            i += 1
        rl.append(i - bi)
        bi = i
        while i < n and s[i] == 'L':
            i += 1
        ll.append(i - bi)
    m = len(rl)
    ans = []
    for i in range(m):
        s = ll[i] + rl[i]
        temp = [0] * s
        if s & 1 == 0:
            temp[rl[i]] = temp[rl[i] - 1] = s // 2
        else:
            if rl[i] > ll[i]:
                temp[rl[i] - 1] = s // 2 + 1
                temp[rl[i]] = s // 2
            else:
                temp[rl[i] - 1] = s // 2
                temp[rl[i]] = s // 2 + 1
            times = max(ll[i], rl[i]) - 1
            if times & 1:
                temp[rl[i] - 1], temp[rl[i]] = temp[rl[i]], temp[rl[i] - 1]
        ans += temp
    print(*ans)


if __name__ == "__main__":
    main()

E
这种一个加一一个减一的操作,应该马上想到其和是不变的
然后遍历可以被总和整除的自然数
对于每个因数,先进行模运算,然后排序,将左边的减1,右边的加1,找到一个分界点。

# -*- coding: utf-8 -*-
# @time     : 2023/6/2 13:30
# @author   : yhdu@tongwoo.cn
# @desc     :
# @file     : atcoder.py
# @software : PyCharm
import bisect
import copy
import sys
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(100010)


def check(arr, k, p):
    t = [x % p for x in arr]
    t.sort()
    n = len(arr)
    pre = 0
    st = sum(t)
    for i in range(n):
        pre += t[i]
        if pre > k:
            return False
        if pre == (n - 1 - i) * p - (st - pre):
            return True
    return False


def main():
    items = sys.version.split()
    if items[0] == '3.10.6':
        fp = open("in.txt")
    else:
        fp = sys.stdin
    n, k = map(int, fp.readline().split())
    a = list(map(int, fp.readline().split()))
    sa = sum(a)
    p = 1
    ans = 0
    while p * p <= sa:
        if sa % p == 0:
            p0, p1 = p, sa // p
            if check(a, k, p0):
                ans = p0
            if check(a, k, p1):
                ans = p1
                break
        p += 1
    print(ans)


if __name__ == "__main__":
    main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值