python模板(备战蓝桥国赛)

目录

bisect

functools.cmp_to_key

gcd和lcm

二分

倍增法(ST)

前缀和,差分

区间合并

双指针(尺取法)

唯一分解定理和质因数分解

回溯,dfs,bfs

迷宫问题(dfs,bfs)

并查集,最小生成树

快速幂

手写排列组合

简单递推dp

背包问题

最长上升子序列,长度

最长公共子序列,长度

最长回文子序列,长度

树状数字和lowbit

约瑟夫环递推公式

质数埃筛


bisect

# 179 日志统计


import bisect


n, d, k = map(int, input().split())
m = [[] for _ in range(int(10e5+50))]
post = set()
for i in range(n):
    ts, id = map(int, input().split())
    post.add(id)
    m[id].append(ts)
post = sorted(post)
for id in post:
    m[id] = sorted(m[id])
    for i in range(len(m[id])):
        td = m[id][i] + d
        if bisect.bisect_left(m[id], td) - i >= k:
            print(id)
            break

functools.cmp_to_key

import functools


def cmp(n1, n2):
    if n1[1] != n2[1]:
        return -1 if n1[1] > n2[1] else 1  # -1升序1降序
    elif n1[2] != n2[2]:
        return -1 if n1[2] > n2[2] else 1
    else:
        return 1 if n1[0] > n2[0] else -1


n = int(input())
scores = []
for i in range(n):
    score = list(map(int, input().split()))
    scores.append([i+1, sum(score)] + score)
scores = sorted(scores, key=functools.cmp_to_key(cmp))
for i in range(5):
    print(scores[i][0], scores[i][1])

gcd和lcm

# gcd: greatest common divisor  最大公约数
# lcm: Least Common Multiple  最小公倍数

def gcd(a, b):
    while b:
        a, b = b, a % b
    return a


print(gcd(12, 15))
# a = 15  b = 12
# a = 12  b = 3
# a = 3  b = 0
# return 3


def lcm(a, b):
    s = a * b
    return s // gcd(a, b)


print(lcm(12, 15))
# 12 * 15 / 3

二分

ls = list(i ** 2 for i in range(1, 11))
print(ls)


def binary_search(n):  # 二分查找基础概念算法
    low = 0
    high = len(ls)
    while low < high:
        mid = (low + high) // 2
        if mid == n:
            return ls[mid]
        elif n < mid:
            high = mid - 1
        else:
            low = mid + 1


n = int(input())
res = binary_search(n)
print(res)


# 二分题目模板

# check函数是核心
def check(x):
    pass
    # 假设x为答案
    # 题目一般有有个约束条件
    # 如果通过某种手段使得在x的条件下存在符合约束条件的解
    # 那么就是可行解


# 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用,把中间点放在左半边,不管三七二十一先用这个,做题过程中再修改
def bsearch_1(l, r):
    while l < r:
        mid = l + r >> 1  # 取中间值
        if check(mid):  # 判断是否满足某种性质
            r = mid  # 更新区间
        else:
            l = mid + 1
    return l


# 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用,把中间点放在左半边(比如左边是合法的,右边是不合法的,此时mid属于合法的那一边)
def bsearch_2(l, r):
    while l < r:
        mid = l + r + 1 >> 1  # 取中间值
        if check(mid):  # 判断是否满足某种性质
            l = mid  # 更新区间
        else:
            r = mid - 1
    return l


倍增法(ST)

# 1205区间最大值

from math import *

N = 100001
dp = [[0] * 40 for i in range(N)]
n, m = map(int, input().split())
a = [0] + list(map(int, input().split()))


def st_init():
    global dp
    for i in range(1, n + 1):
        dp[i][0] = a[i]  # dp[s][k]表示左端点是s,区间长度为2**k的区间最值
        p = int(log2(n))
        for k in range(1, p + 1):
            for s in range(1, n + 2 - (1 << k)):  # 1<<(k-1) 表示2的k-1次方
                dp[s][k] = max(dp[s][k - 1], dp[s + (1 << (k - 1))][k - 1])


def st_query(L, R):
    k = int(log2(R - L + 1))
    return max(dp[L][k], dp[R - (1 << k) + 1][k])


st_init()
for i in range(1, m + 1):
    L, R = map(int, input().split())
    print(st_query(L, R))

前缀和,差分

# # 前缀和模板(一维)
# a = [0] + list(map(int, input().split()))
# s = [0] * len(a)
# for i in range(1, len(a)+1):
#     s[i] = s[i - 1] + a[i]
# print(a, s, sep='\n')
# left, right = map(int, input().split())
# print(s[right] - s[left])  # a[left+1]到a[right]间所有数的和

# print("------------------")
# # 前缀和模板(二维)
# # S[i][j] = a[i][j] + S[i-1][j] + S[i][j-1] - S[i-1][j-1]
# # ----S[i-1][j-1]为S[i-1][j]和S[i][j-1]重叠部分,多加了一次,故减掉
# n, m = map(int, input().split())  # n行m列
# a = [[0] * (m+1)] + [[0] + list(map(int, input().split())) for i in range(n)]
# s = [[0] * (m+1) for i in range(n+1)]
# for i in range(1, n+1):
#     for j in range(1, m+1):
#         s[i][j] = a[i][j] + s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1]
# print(a, s, sep='\n')
# left_x, left_y, right_x, right_y = map(int, input().split())
# print(s[right_x][right_y] - s[left_x][left_y])


# 差分模板(一维)
a = [0, 1, 2, 3, 4]
b = [0] * 5
for i in range(1, len(a)):
    b[i] = b[i - 1] + a[i]
print(a, b, sep='\n')  # a是b的差分数组,b是a的前缀和数组

print("----------------")
# 构建差分数组
c = [0, 1, 2, 3, 4]
print(c)
d = c[:]
e = c[:]
for i in range(1, len(d)):
    d[i] = d[i] + d[i - 1]
print(d)
l, r = 1, 3
e[l] += 1
e[r + 1] -= 1
for i in range(1, len(e)):
    e[i] += e[i - 1]
print(e)

# 例题真题14: 重新排序(前缀和,差分)
#    真题15:  k倍区间(前缀和)


# 矩阵前缀和案例 2109 统计子矩阵
n, m, k = map(int, input().split())
a = [[0] for i in range(n)]
a.insert(0, [0] * (m + 1))
for i in range(1, n + 1):
    a[i].extend(map(int, input().split()))
s = [[0] * (m + 1) for i in range(n + 1)]
for i in range(1, n + 1):
    for j in range(1, m + 1):
        s[i][j] = a[i][j] + s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1]
ans = 0
for i1 in range(1, n + 1):
    for i2 in range(i1, n + 1):
        for j1 in range(1, m + 1):
            for j2 in range(j1, m + 1):
                z = s[i2][j2] - s[i1 - 1][j2] - s[i2][j1 - 1] + s[i1 - 1][j1 - 1]
                if z <= k:
                    ans += 1
print(ans)


# 2109 双指针优化版
n, m, k = map(int, input().split())
a = [[0] for i in range(n)]
a.insert(0, [0] * (m+1))
for i in range(1, n+1):
    a[i].extend(map(int, input().split()))
s = [[0] * (m+1) for i in range(n+1)]
for i in range(1, 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值