CCF CAT- 全国算法精英大赛(2024第二场)往届真题练习 2 | 珂学家


前言

这是第二场CCF的练习赛,找找手感,顺便熟悉下赛氪OJ平台。

当前就做了5题,感觉还可以,部分题目质量蛮高的,但是易错。

第1题dp入门题, 第5属于诈骗题,第2和第3挺有难度的,第四题感觉放水了。
在这里插入图片描述


真题

Hotpot

在这里插入图片描述

思路: 状态机DP

这是时间复杂度为 o ( n ) o(n) o(n)

应该是存在矩阵幂的解法的

n = int(input())

s0, s1, s2, s3 = 1, 0, 0, 0

mod = 10 ** 9 + 7
for i in range(n):
  s0, s1, s2, s3 = s0 + s1 + s2 + s3, s0 + s2, s0 + s1, s0
  s0 %= mod
  s1 %= mod
  s2 %= mod
  s3 %= mod

print ((s0+s1+s2+s3)%mod)

Hearthstone

在这里插入图片描述

思路:环型DP

其实也是线性DP,无非多了一个环型限制,题目保证n为偶数。

# 思维题

n = int(input())

arr = []
for _ in range(n):
  v1, v2, v3 = list(map(int, input().split()))
  arr.append((v1, v2, v3))

from math import inf
def solve(f, tag):
    if tag == 1 and f == 2:
      return 0
    if tag == 0 and f == 0:
      return 0
    dp = [-inf] * 3
    dp[f] = arr[0][f]
    
    for i in range(1, n):
        v1, v2, v3 = arr[i]
        dp2 = [-inf] * 3
        if i % 2 == tag:
            dp2[1] = dp[0] + v2
            dp2[2] = max(dp[0], dp[1]) + v3
        else:
            dp2[0] = max(dp[1], dp[2]) + v1
            dp2[1] = dp[2] + v2
        dp = dp2
    res = 0
    for i in range(3):
        if tag == 0 and f > i:
            res = max(res, dp[i])
        elif tag == 1 and f < i:
            res = max(res, dp[i])
    return res

ans = 0
for i in range(0, 3):
    for j in (0, 1):
        ans = max(ans, solve(i, j))

print (ans)

Best Travel Plans

在这里插入图片描述

思路: 反悔堆

挺难的这题,一开始普通的BFS写法,TLE到奔溃

然后想了想,是不是可以枚举最远的位子,然后贪心求解。

这样的话,就可以构建反悔堆求解最优场景了。

n, T = list(map(int, input().split()))

es = list(map(int, input().split()))
us = list(map(int, input().split()))
vs = list(map(int, input().split()))

from math import inf
import heapq

hq = []

res = 0
tmp = 0
acc = 0
for i in range(n):
    if i > 0:
       acc += es[i - 1]
    if acc > T:
        break
    while acc + len(hq) > T and len(hq) > 0:
        tmp -= heapq.heappop(hq)

    j = 0
    while True:
        ng = us[i] - j * vs[i]
        if ng <= 0:
            break
        if acc + len(hq) < T:
            heapq.heappush(hq, ng)
            tmp += ng
        else:
            if len(hq) > 0 and hq[0] >= ng:
                break
            tmp -= heapq.heappop(hq)
            heapq.heappush(hq, ng)
            tmp += ng
        j += 1
    res = max(res, tmp)

print (res)

Tree

在这里插入图片描述

解题突破口: n ≤ 1000 n \le 1000 n1000

这题就是单纯的模拟,就算二叉搜索树退化为链表,最多 O ( n 2 ) O(n^2) O(n2)

涉及DFS操作,采用java编写

import java.io.BufferedInputStream;
import java.util.Scanner;

public class Main {

    static class TreeNode {
        int val;
        TreeNode left, right;
        public TreeNode(int val) {
            this.val = val;
        }

        public void insert(int v) {
            if (this.val == v) return;
            if (this.val > v) {
                if (this.left == null) {
                    this.left = new TreeNode(v);
                    return;
                }
                this.left.insert(v);
            } else if (this.val < v) {
                if (this.right == null) {
                    this.right = new TreeNode(v);
                    return;
                }
                this.right.insert(v);
            }
        }

        public int insert(int v, int depth) {
            if (this.val == v) return depth;
            else if (this.val > v) {
                if (this.left == null) {
                    return depth + 1;
                }
                return this.left.insert(v, depth + 1);
            } else {
                if (this.right == null) {
                    return depth + 1;
                }
                return this.right.insert(v, depth +1);
            }
        }

    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(new BufferedInputStream(System.in));
        int n = sc.nextInt();

        TreeNode root = null;
        int v = sc.nextInt();
        root = new TreeNode(v);
        for (int i = 1; i < n; i++) {
            int t = sc.nextInt();
            root.insert(t);
        }

        for (int i = 0; i < n; i++) {
            int t = sc.nextInt();
            System.out.println(root.insert(t, 1));
        }
    }

}

Flower

在这里插入图片描述

思路: 排序即可

题目感觉有些绕,挺无语的,小诈骗吧

n, k = list(map(int, input().split()))

arr = list(map(int, input().split()))
brr = list(map(int, input().split()))

ls = brr
ls.sort(key=lambda x: -x)

res = 0
for i in range(min(k, len(ls))):
  res += ls[i]
print (res)

写在最后

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值