CSP 2023 提高级第一轮 CSP-S 2023初试题 程序阅读第三题解析

2024-09-01 03:44

本文主要是介绍CSP 2023 提高级第一轮 CSP-S 2023初试题 程序阅读第三题解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

三、完善程序(单选题,每小题 3 分,共计 30 分)

一、题目阅读

(第 k 小路径)给定一张 n 个点 m 条边的有向无环图,定点编号从 0 到 n−1,对于一条路径,我们定义“路径序列”为该路径从起点出发依次经过的顶点编号构成的序列。求所有至少包含一个点的简单路径中,“路径序列”字典序第 k 小的路径。保证存在至少 k 条路径。上述参数满足 1≤n,m≤105,1≤k≤1018。

在程序中,我们求出从每个点出发的路径数量。超过 1018 的数都用 1018 表示。然后我们根据 k 的值和每个顶点的路径数量,确定路径的起点,然后可以类似地依次求出路径中的每个点。

试补全程序。

#include <iostream>
#include <algorithm>
#include <vector>const int MAXN = 100000;
const long long LIM = 1000000000000000000ll;int n, m, deg[MAXN];
std::vector<int> E[MAXN];
long long k, f[MAXN];int next(std::vector<int> cand, long long &k) {std::sort(cand.begin(), cand.end());for (int u : cand) {if (①) return u;k -= f[u];}return -1;
}int main() {std::cin >> n >> m >> k;for (int i = 0; i < m; ++i) {int u, v;std::cin >> u >> v; // 一条从u到v的边E[u].push_back(v);++deg[v];}std::vector<int> Q;for (int i = 0; i < n; ++i)if (!deg[i]) Q.push_back(i);for (int i = 0; i < n; ++i) {int u = Q[i];for (int v : E[u]) {if (②)Q.push_back(v);--deg[v];}}std::reverse(Q.begin(), Q.end());for (int u : Q) {f[u] = 1;for (int v : E[u])f[u] = ③;}int u = next(Q, k);std::cout << u << std::endl;while (④) {⑤;u = next(E[u], k);std::cout << u << std::endl;}return 0;
}

二、代码分析

题目地意思是有一张有向无环图,任意一个顶点开始通过相连边到达某个顶点算一个路径,比如说1,2有边相连,那么1算一条路径,1 -> 2算一条路径,2也算一条。

按字典序排好后就是:1,1 -> 2,2。

代码解析:

首先处理各个顶点之间的关系,并拓扑排序,然后倒过来(这是动态规划的常态,从最后开始。变色部分会解释)

接下来时整个推算过程。

f[i]表示以 i 为起点的路径总数,那么我们可以推算出这样的一个公式。

f[u] = f[E[u][0]]+f[E[u][1]]+...+f[E[u][n]]   +  1

E[u][1, 2, ... , n]代表u的邻接节点。

为什么呢?假设u只有一个邻接节点v,u为起点的路径总数个数是1(u->v) + f[v](u->v->...,其中v->...部分就是f[v])。

看到第41行,我们知道 f 数组是用来存放以某个节点为起点的路径数量,那么我们应该去遍历它的每个邻接节点,这就是为什么要反转结果了,反转之后,与其他关联最多的总是已经处理(请注意,拓扑排序不是那度数排序!别踩坑)。

然后我们计算出以它为起点出发的路径数量。

next函数的作用如下:

        接着我们第一次调用next函数。

        cand就是Q。

        将它排好序之后就是第一个顶点的选择,那么按字典序来肯定选最小的啊,所以我们取了第一个元素。

        接着按照题意,我们应该看看,我以u做起点的路径个数够不够k,如果够了,那么就不要往下了,反正肯定就是以u开始了。如果不够,那还要取下一个节点做开始,以此类推......

        当够了的时候,我们要把k减小,减小前面的总个数。(这好比把单位一点一点缩小)

        接着每次将对应起点的临界矩阵送给next函数同样道理地处理......

三、题目分析

1. ①处应填()

A. k >= f[u]

B.  k <= f[u]
C.  k > f[u]
D.  k < f[u]

2. ②处应填()

A. deg[v] == 1

B.  deg[v] == 0
C.  deg[v] > 1
D.  deg[v] > 0

3. ③处应填()

A. std::min(f[u] + f[v], LIM)

B.  std::min(f[u] + f[v] + 1, LIM)
C.  std::min(f[u] * f[v], LIM)
D.  std::min(f[u] * (f[v] + 1), LIM)

4. ④处应填()

A. u != -1

B. !E[u].empty()

C. k > 0
D.  k > 1

5. ⑤处应填()

A. K+=f[u]

B.  k-=f[u]
C. --k
D. ++k

这篇关于CSP 2023 提高级第一轮 CSP-S 2023初试题 程序阅读第三题解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1125851

相关文章

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

一文解析C#中的StringSplitOptions枚举

《一文解析C#中的StringSplitOptions枚举》StringSplitOptions是C#中的一个枚举类型,用于控制string.Split()方法分割字符串时的行为,核心作用是处理分割后... 目录C#的StringSplitOptions枚举1.StringSplitOptions枚举的常用

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

MyBatis延迟加载与多级缓存全解析

《MyBatis延迟加载与多级缓存全解析》文章介绍MyBatis的延迟加载与多级缓存机制,延迟加载按需加载关联数据提升性能,一级缓存会话级默认开启,二级缓存工厂级支持跨会话共享,增删改操作会清空对应缓... 目录MyBATis延迟加载策略一对多示例一对多示例MyBatis框架的缓存一级缓存二级缓存MyBat

前端缓存策略的自解方案全解析

《前端缓存策略的自解方案全解析》缓存从来都是前端的一个痛点,很多前端搞不清楚缓存到底是何物,:本文主要介绍前端缓存的自解方案,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、为什么“清缓存”成了技术圈的梗二、先给缓存“把个脉”:浏览器到底缓存了谁?三、设计思路:把“发版”做成“自愈”四、代码

Java集合之Iterator迭代器实现代码解析

《Java集合之Iterator迭代器实现代码解析》迭代器Iterator是Java集合框架中的一个核心接口,位于java.util包下,它定义了一种标准的元素访问机制,为各种集合类型提供了一种统一的... 目录一、什么是Iterator二、Iterator的核心方法三、基本使用示例四、Iterator的工

java程序远程debug原理与配置全过程

《java程序远程debug原理与配置全过程》文章介绍了Java远程调试的JPDA体系,包含JVMTI监控JVM、JDWP传输调试命令、JDI提供调试接口,通过-Xdebug、-Xrunjdwp参数配... 目录背景组成模块间联系IBM对三个模块的详细介绍编程使用总结背景日常工作中,每个程序员都会遇到bu

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni