第三届大学生算法大赛(通过率低于14%部分)

B题 经济(通过率10.08%)

题目描述:

理解题目

  • 游戏分为四局,初始金币为0。
  • 每一局可以存下或花费1到n个金币。
  • 前两局先存钱,后两局再花钱。
  • 最终手上正好剩下k个金币。
  • 需要计算有多少种方法可以达到这个目标。

解题思路

  • 前两局存钱,设第一局存x个金币,第二局存y个金币。
  • 后两局花钱,设第三局花费a个金币,第四局花费b个金币。
  • 满足条件 x + y - a - b = k
  • 需要枚举前两局存钱的组合,计算后两局的组合数,累加符合条件的方案总数。

代码实现

# 读取输入的两个整数 n 和 k,表示每一局可以存下或者花费的金币数上限,以及最后想剩下的金币数量。
n, k = map(int, input().split())

# 初始化方案总数为0
s = 0

# 初始化前两局的累积存钱数为0
a, b = 0, 0

# 初始化`a`和`b`的增减方向
af, bf = 1, 1

# 枚举前两局存钱的累积金额,范围从2到2*n
for i in range(2, 2 * n + 1):
    # 当a达到n时,改变方向为减少
    if a == n:
        af = -1
    # 当b达到n时,改变方向为减少
    if b == n:
        bf = -1
    # 更新a的值
    a += af
    # 当i大于等于k+2时,更新b的值
    if i >= k + 2:
        b += bf
    # 累加符合条件的方案数
    s += a * b

# 输出方案总数
print(s)

E题 韩信点兵(通过率13.4%)

题目描述:

F题 掩护推进(通过率2.31%)

题目描述:

I题 秘密通信(通过率9.88%)

题目描述:

解题思路:

  1. 读取输入

    • 读取一个字符串 S,表示混淆过后的信息。
  2. 处理字符串

    • 遍历字符串 S 中的每个字符。
    • 如果当前字符不是 'f',直接将该字符添加到临时列表 lt 中。
    • 如果当前字符是 'f',则需要检查前两个字符是否分别是 't' 和 'w':
      • 如果是,则这表明遇到了一个完整的 "wtf" 子串,忽略这三个字符。
      • 如果不是,则需要将之前弹出的字符重新添加回列表 lt 中,并添加当前的 'f' 字符。
  3. 输出结果

    • 将列表 lt 中的字符连接成字符串,并输出。

代码实现:

# 初始化一个列表来存储处理后的字符
lt = []

# 读取输入的字符串 S
for c in input():
    # 如果当前字符不是 'f',直接添加到列表中
    if c != 'f':
        lt.append(c)
    else:
        # 如果当前字符是 'f',则需要检查前两个字符
        # 弹出列表中的最后一个字符
        b = lt.pop()
        # 如果弹出的字符是 't',则再弹出一个字符检查是否为 'w'
        if b == 't':
            a = lt.pop()
            # 如果弹出的字符是 'w',则这表明遇到了一个完整的 "wtf" 子串
            # 忽略这三个字符,不做任何操作
            if a == 'w':
                pass
            # 如果弹出的字符不是 'w',则将之前弹出的字符重新添加回列表,并添加当前的 'f'
            else:
                lt.append(a)
                lt.append(b)
                lt.append(c)
        # 如果弹出的字符不是 't',则将之前弹出的字符重新添加回列表,并添加当前的 'f'
        else:
            lt.append(b)
            lt.append(c)

# 将列表中的字符连接成字符串,并输出
print(''.join(lt))

 J题 地下交易(通过率13.42%)

题目描述:

理解题目

  • 给定一个整数 n 表示代理人的数量。
  • 给定一个长度为 n 的整数列表 p,表示每个代理人在交易后所持有的商品编号。
  • 需要判断这种交易结果是否可以通过指定的交换过程实现。

分析交易过程

  • 每个代理人(除了最后一个)会与其下一个代理人交换一次商品。
  • 也就是说,对于编号为 i(1 ≤ i < n)的代理人,他会和编号为 i+1 的代理人交换商品。
  • 交易完成后,每个代理人的商品编号应该是 p[i]

验证交易结果

  • 我们可以通过模拟交易过程来验证交易结果是否合法。
  • 从第一个代理人开始,跟踪商品的流动路径,直到所有商品都被正确分配。
  • 如果所有商品都被正确分配,并且每个代理人都恰好进行了交换,那么交易结果是合法的。
  • 否则,交易结果是非法的。

代码实现:

# 读取测试用例的数量
for _ in range(int(input())):
    # 读取代理人的数量 n
    n = int(input())
    # 读取交易后的结果 p
    lt = list(map(int, input().split()))
    
    # 初始化计数器 t 和索引 i
    t, i = 0, 0
    
    # 使用标记 -1 来表示已经被处理的商品
    while lt[i] != -1:
        # 获取当前代理人 i 应持有的商品编号 k
        k = lt[i]
        # 将当前商品标记为已处理
        lt[i] = -1
        # 转移到下一个代理人
        i = k - 1
        # 计数器加一
        t += 1
    
    # 如果计数器 t 等于代理人数量 n,则交易结果合法,否则非法
    print(1 if t == n else -1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值