2024.6.23刷题记录

目录

一、P1102 A-B 数对 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

1.hash表-一次遍历

2.双指针(同向,可以算滑动窗口)-排序

 二、P8667 [蓝桥杯 2018 省 B] 递增三元组 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

1.排序+指针

2.排序+二分

三、12. 整数转罗马数字

1.模拟

 2.模拟2-贪心

 四、【模板】快速幂 - 洛谷

 五、876. 快速幂求逆元 - AcWing题库


一、P1102 A-B 数对 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

1.hash表-一次遍历

时复O(n),空复O(n)。

# 一次遍历
n, c = map(int, input().split())
nums = list(map(int, input().split()))
ans = 0
hash = {}
for x in nums:
    if x - c in hash:
        ans += hash[x - c]
    if x + c in hash:
        ans += hash[x + c]
    hash[x] = hash.get(x, 0) + 1
print(ans)

2.双指针(同向,可以算滑动窗口)-排序

参考题解(题解 P1102 【A-B 数对】 - 洛谷专栏 (luogu.com.cn))。时复O(nlogn),空复O(1)。

# 双指针(同向,应该算滑动窗口)-排序
n, c = map(int, input().split())
nums = list(map(int, input().split()))
nums.sort()
ans = 0
# 维护区间差为c的窗口
left1, left2 = 0, 0
for right in range(n):
    # 这里还有点二分的味道
    while nums[right] - nums[left1] > c:
        # 这里left不会超界,因为left最多到right就停
        left1 += 1
    while nums[right] - nums[left2] >= c:
        left2 += 1
    if nums[right] - nums[left1] == c:
        ans += left2 - left1
print(ans)

 二、P8667 [蓝桥杯 2018 省 B] 递增三元组 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

1.排序+指针

时复O(n^2),超时了。

 代码:

# 排序+指针
n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
c = list(map(int, input().split()))
a.sort()
b.sort()
c.sort()
ans = 0
j, k = 0, 0
for anum in a:
    while j < n and b[j] <= anum:
        # 将j调到对应位置
        j += 1

    if j < n:
        bnum = b[j]
    else:
        continue

    while k < n and c[k] <= bnum:
        # 调整k
        k += 1
    jj = j
    kk = k
    while jj < n:
        # a < b
        bnum = b[jj]
        while kk < n and c[kk] <= bnum:
            # 调整kk
            kk += 1
        ans += n - kk
        jj += 1
print(ans)

2.排序+二分

来自题解(P8667 [蓝桥杯 2018 省 B] 递增三元组 题解 - 洛谷专栏 (luogu.com.cn)),太帅了!时复O(nlogn),通过。

# 排序+二分
import bisect # 二分库

n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
c = list(map(int, input().split()))
a.sort()
b.sort()
c.sort()
ans = 0
# 枚举处于中间的b
for bnum in b:
    cnt_a = bisect.bisect_left(a, bnum)
    cnt_c = n - bisect.bisect_right(c, bnum)
    ans += cnt_a * cnt_c
print(ans)

三、12. 整数转罗马数字

1.模拟

class Solution:
    def intToRoman(self, num: int) -> str:
        # 模拟
        ans = ''
        while num > 0:
            if num <= 9:
                if num == 9:
                    ans += 'IX'
                    num -= 9
                elif num == 4:
                    ans += 'IV'
                    num -= 4
                elif num >= 5:
                    ans += 'V'
                    num -= 5
                while num >= 1:
                    ans += 'I'
                    num -= 1
            elif num <= 99:
                if num >= 90:
                    ans += 'XC'
                    num -= 90
                elif 49 >= num >= 40:
                    ans += 'XL'
                    num -= 40
                elif num >= 50:
                    ans += 'L'
                    num -= 50
                while num >= 10:
                    ans += 'X'
                    num -= 10
            elif num <= 999:
                if num >= 900:
                    ans += 'CM'
                    num -= 900
                elif 499 >= num >= 400:
                    ans += 'CD'
                    num -= 400
                elif num >= 500:
                    ans += 'D'
                    num -= 500
                while num >= 100:
                    ans += 'C'
                    num -= 100
            else:
                while num >= 1000:
                    ans += 'M'
                    num -= 1000
        return ans

 2.模拟2-贪心

来自官方题解(. - 力扣(LeetCode))。

class Solution:
    VALUE_SYMBOLS = [
        (1000, "M"),
        (900, "CM"),
        (500, "D"),
        (400, "CD"),
        (100, "C"),
        (90, "XC"),
        (50, "L"),
        (40, "XL"),
        (10, "X"),
        (9, "IX"),
        (5, "V"),
        (4, "IV"),
        (1, "I"),
    ]
    def intToRoman(self, num: int) -> str:
        # 模拟2
        roman = ''
        for value, symbol in Solution.VALUE_SYMBOLS:
            while num >= value:
                num -= value
                roman += symbol
            if num == 0:
                break
        return roman

 四、【模板】快速幂 - 洛谷

'''
快速幂模板题
'''
a, b, p = map(int, input().split())
def binpow(a, b, p):
    res = 1
    a %= p
    while b > 0:
        # 将每一位的值乘上去(指数是加,幂数是乘)
        if b & 1:
            res = res * a % p   # 对当前值进行取模
        b >>= 1
        a = a * a % p
    return res
print(f"{a}^{b} mod {p}={binpow(a, b, p)}")

 五、876. 快速幂求逆元 - AcWing题库

# 辗转相除法求最大公因数
def gcd(a, b):
    if a < b:
        return gcd(b, a)  # 大的放前面
    while b > 0:
        a, b = b, a % b
    return a

def qmi(a, n, mod):
    ans = 1
    a %= mod
    while n:
        if n & 1:
            ans = ans * a % mod
        a = a * a % mod
        n >>= 1
    return ans

n = int(input())
for _ in range(n):
    a, q = map(int, input().split())
    if gcd(a, q) != 1:
        print('impossible')
        continue
    print(qmi(a, q - 2, q))

 完

感谢你看到这里!一起加油吧!

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值