CF-Harbour-Div1

C-D

1864C. Divisor Chain

英文原题
题目简述,把一个数字x,通过减法变成1。被减数只能是减数的除法因子,且每个因子的使用次数不得超过两次。
从二进制的角度考虑除法因子。
比如十进制整数14,可以转成二进制1110。
那么可以每次减去(末尾最后一个1)10,100,然后得到1000。然后再依次减去100,10,1得到1,显然每个因子的使用次数最多是两次,非常地符合题意,这个方法太妙了。
时间复杂度 log(n)
空间复杂度 log(n)

# import sys
#
# sys.stdin = open('input.txt', 'r')
 
 
def divisor_chain(n):
    k = n
    bits = []
    while k > 0:
        bits.append(k % 2)
        k = k // 2
    # print(bits)
    ans = [n]
    k = n
    for i in range(len(bits)-1):
        if bits[i]:
            k = k - (1 << i)
            ans.append(k)
    for i in range(len(bits)-2, -1, -1):
        k = k - (1 << i)
        ans.append(k)
    print(len(ans))
    print(' '.join(str(x) for x in ans))
 
 
def main():
    tcn = int(input())
    for _ in range(tcn):
        n = int(input())
        divisor_chain(n)
 
 
if __name__ == '__main__':
    main()

1864D. Matrix Cascade

英文描述
模拟法,一层一层向下传递,需要注意翻转状态的保留和翻转次数的计算。
1->3->5,一层一层的扩张。
传播示例图
其他技巧:差分数组,动态规划。

import sys

# sys.setrecursionlimit(10000)


def input_general():
    return sys.stdin.readline().rstrip('\r\n')


def input_num():
    return int(sys.stdin.readline().rstrip("\r\n"))


def input_multi(x=int):
    return map(x, sys.stdin.readline().rstrip("\r\n").split())


def input_list(x=int):
    return list(input_multi(x))


def main():
    n = input_num()
    arr = []
    for _ in range(n):
        s = input_general()
        arr.append(s)

    click = [[0 for _ in range(n)] for _ in range(n)]
    need = [[0 for _ in range(n)] for _ in range(n)]

    for i in range(n):
        for j in range(n):
            cl = 0
            if i >= 1:
                if j == 0:
                    cl = click[i - 1][j + 1] + need[i - 1][j]
                elif j == n - 1:
                    cl = click[i - 1][j - 1] + need[i - 1][j]
                else:
                    cl = click[i - 1][j - 1] + click[i - 1][j + 1]
                    if i >= 2:
                        cl -= click[i - 2][j]
                    cl += need[i - 1][j]

            ne = (int(arr[i][j]) + cl) % 2
            need[i][j] = ne
            click[i][j] = cl + ne

    # print(need, click)
    print(sum(sum(row) for row in need))


if __name__ == "__main__":
    cases = input_num()

    for _ in range(cases):
        main()

参考
参考链接一
参考链接二

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值