第七届传智杯初赛第二场(abc三组)Python题解详解与补题攻略

文章目录

  • 前言
  • A 计算商品打折结算金额(B组、C组)
  • B 茶杯和球(A组、C组)
  • C 游游的字母串(A组、B组、C组)
  • D 电梯(B组、C组)
  • E 小欧的排列计算(A组、B组、C组)
  • F 游游的字母子串(A组、B组、C组)
  • G 跳跳跳(A组、B组)
  • H 小红的战争棋盘(A组)

  • 前言


    在CSDN上并未找到第七届传智杯初赛第二场的相关题解,于是自己写了一个供大家参考。
    附上补题链接 点此进入https://ac.nowcoder.com/acm/contest/100449#question


    A 计算商品打折结算金额(B组、C组)

    思路分析:

    通过f-string格式化输出(python3.6以上)

    题解:

    n = float(input())
    if n >= 5000:
        ans = n * 0.6
    elif n >= 2000:
        ans = n * 0.7
    elif n >= 500:
        ans = n * 0.8
    elif n >= 100:
        ans = n * 0.9
    else:
        ans = n
    print(f"{ans:.1f}")
    

    B 茶杯和球(A组、C组)

    思路分析:

    将球所在的杯子打上标记即可

    题解:

    n, x, k = map(int, input().split())
    a = [0] * n
    a[x - 1] = 1
    for _ in range(k):
        i, j = map(int, input().split())
        a[i - 1], a[j - 1] = a[j - 1], a[i - 1]
    print(a.index(1) + 1)
    

    C 游游的字母串(A组、B组、C组)

    思路分析:

    仅包含小写字符串,最后所有元素要求变成相同的。因为只有26种情况,不妨从答案入手,逆向解题:
    遍历从a到z,通过check函数返回需要的次数。

    题解:

    from math import inf
    
    s = input()
    ans = float(inf)
    
    
    def check(x):
        sum = 0
        for i in s:
            res = abs(ord(i) - x)
            if res > 13:
                res = 26 - res
            sum += res
        return sum
    
    
    for i in range(97, 123):
        ans = min(ans, check(i))
    
    

    D 电梯(B组、C组)

    思路分析:

    简单的模拟题:sum1和sum2分别表示两个电梯各自的时间

    题解:

    n = int(input())
    a = list(map(int, input().split()))
    sum1 = a[0] 
    sum2 = a[1]  # 初始化
    for i in range(2, n):
        if sum1 < sum2:
            sum1 += a[i]
        else:
            sum2 += a[i]
    print(max(sum1, sum2))
    

    E 小欧的排列计算(A组、B组、C组)


    思路分析:

    所有相邻两个数的乘积均为偶数 即两个奇数不会相邻
    数学排列组合(插空法 )偶数排列完后将奇数插入空中 A(偶,偶)*C(偶+1,奇)*A(奇,奇)
    涉及到的预计算阶乘、逆元求组合数可查看我的博客 [点此进入]

    题解:

    mod = 10 ** 9 + 7
    
    def C(n, m):
        p, q = 1, 1
        for i in range(1, m + 1):
            p = p * (n - i + 1) % mod
            q = q * i % mod
        return p * pow(q, mod - 2, mod) % mod
    
    def A(n, m):
        p = 1
        for i in range(1, m):
            p = p * (n - i + 1) % mod
        return p % mod
    
    n = int(input())
    even = n // 2  # 偶数个数
    odd = n - even  # 奇数个数
    # A(odd,odd)*A(even,even)*C(even+1,odd)
    print(A(odd, odd) * A(even, even) * C(even + 1, odd) % mod)
    

    F 游游的字母子串(A组、B组、C组)

    思路分析:

    连续子串常常使用滑动窗口技术【详细全面讲解点此进入】。
    1.维护一个有条件的不定长滑动窗口;
    2.右端点右移,导致窗口扩大,不满足条件;
    3.左端点右移,为了缩小窗口,重新满足条件

    种类不超过k可以使用哈希表(字典)统计个数实现
    数据结构defaultdict相关用法 可见我的博客 点此进入

    题解:

    from collections import defaultdict
    
    n, k = map(int, input().split())
    s = input()
    ans = left = 0
    dict = defaultdict(int)  
    for right in range(n):
        dict[s[right]] += 1
        while len(dict) > k:
            dict[s[left]] -= 1
            if dict[s[left]] == 0:
                dict.pop(s[left])
            left += 1
    
        ans = max(ans, right - left + 1)
    print(ans)
    
    

    G 跳跳跳(A组、B组)



    思路分析:

    环形区间DP问题

    【算法】动态规划专题⑫ —— 环形区间DP python

    题解:

    n = int(input())
    a = list(map(int, input().split()))
    a += a
    dp = [[0] * n * 2 for _ in range(n * 2)]
    for i in range(n * 2):
        dp[i][i] = a[i]
    
    for len in range(2, n + 1):
        for i in range(n * 2 - len):
            j = i + len - 1
            step = len
            dp[i][j] = max(dp[i + 1][j] + a[i] * step, dp[i][j - 1] + a[j] * step)
    ans = 0
    for i in range(n):
        ans = max(ans, dp[i][i + n - 1])
    print(ans)
    

    H 小红的战争棋盘(A组)



    示例一:
    输入:

    3 3 2
    ranko 1 1
    kotori 2 2
    5
    ranko D
    ranko W
    ranko A
    kotori W
    kotori W
    

    输出:

    vanquish!
    out of bounds!
    peaceful.
    ranko wins!
    unexisted empire.
    

    思路分析:

    大模拟太麻烦哩,最后选择放弃。
    有做出来的小伙伴可以留言讨论哦!

    作者:查理零世

    物联沃分享整理
    物联沃-IOTWORD物联网 » 第七届传智杯初赛第二场(abc三组)Python题解详解与补题攻略

    发表回复