image

编辑人: 独留清风醉

calendar2025-07-24

message8

visits494

全国信息学奥林匹克联赛(NOIP2018)复赛 提高组 day2参考答案

一、实操题

1、旅行

【问题描述】

小 Y 是一个爱好旅行的 OIer。她来到 X 国,打算将各个城市都玩一遍。

小 Y 了解到,X 国的n 个城市之间有 m 条双向道路。每条双向道路连接两个城市。不存在两条连接同一对城市的道路,也不存在一条连接一个城市和它本身的道路。并且,从任意一个城市出发,通过这些道路都可以到达任意一个其他城市。小 Y 只能通过这些道路从一个城市前往另一个城市。

小 Y 的旅行方案是这样的:任意选定一个城市作为起点,然后从起点开始,每次可以选择一条与当前城市相连的道路,走向一个没有去过的城市,或者沿着第一次访问该城市时经过的道路后退到上一个城市。当小 Y 回到起点时,她可以选择结束这次旅行或继续旅行。需要注意的是,小 Y 要求在旅行方案中,每个城市都被访问到。

为了让自己的旅行更有意义,小 Y 决定在每到达一个新的城市(包括起点)时,将它的编号记录下来。她知道这样会形成一个长度为n 的序列。她希望这个序列的字典序最小,你能帮帮她吗?

对于两个长度均为 n 的序列 A 和 B,当且仅当存在一个正整数 x,满足以下条件时,我们说序列 A 的字典序小于 B。

⚫ 对于任意正整数 1 ≤ i < x,序列 A 的第 i 个元素 Ai 和序列 B 的第 i 个元素Bi 相同。

⚫ 序列 A 的第 x 个元素的值小于序列 B 的第 x 个元素的值。

【输入格式】

输入文件名为 travel.in。

输入文件共 m + 1 行。第一行包含两个整数 n, m(m ≤ n) ,中间用一个空格分隔。

接下来 m 行,每行包含两个整数 u, v (1 ≤ u, v ≤ n) ,表示编号为 u 和 v 的城市之间有一条道路,两个整数之间用一个空格分隔。

【输出格式】

输出文件名为 travel.out。

输出文件包含一行,n 个整数,表示字典序最小的序列。相邻两个整数之间用一个空格分隔。

【输入输出样例 1】

【输入输出样例 2】

【数据规模与约定】

对于 100% 的数据和所有样例,1 ≤ n ≤ 5000 且 m = n − 1 或 m = n 。

对于不同的测试点,我们约定数据的规模如下:

参考答案:对于本题,我们可以使用拓扑排序算法来解决。首先,我们需要构建出图的邻接表表示,然后对每个节点的入度进行统计。由于每个城市都能通过道路到达其他城市,因此,对于入度为0的节点,我们可以按照任意顺序进行访问,使得整个序列的字典序最小。具体的,我们可以按照邻接表的顺序进行拓扑排序,如果当前节点没有被访问过,且其入度为0,则将其加入结果序列中,并将其所有邻居的入度减1。重复这个过程,直到所有的节点都被访问过。


2、 填数游戏

【问题描述】

小 D 特别喜欢玩游戏。这一天,他在玩一款填数游戏。

这个填数游戏的棋盘是一个n × m的矩形表格。玩家需要在表格的每个格子中填入一个数字(数字 0 或者数字 1),填数时需要满足一些限制。

下面我们来具体描述这些限制。

为了方便描述,我们先给出一些定义:

• 我们用每个格子的行列坐标来表示一个格子,即(行坐标,列坐标)。(注意:行列坐标均从 0 开始编号)

• 合法路径 P:一条路径是合法的当且仅当:

1. 这条路径从矩形表格的左上角的格子(0,0)出发,到矩形的右下角格子(n − 1, m − 1)结束;

2. 在这条路径中,每次只能从当前的格子移动到右边与它相邻的格子,或者从当前格子移动到下面与它相邻的格子。

例如:在下面这个矩形中,只有两条路径是合法的,它们分别是p1:(0,0) → (0,1) →(1,1)和p2:(0,0) → (1,0) → (1,1)。

对于一条合法的路径 P,我们可以用一个字符串w(P)来表示,该字符串的长度为n +m − 2,其中只包含字符“R”或者字符“D”,第 i 个字符记录了路径 P 中第 i 步的移动方法,“R”表示移动到当前格子右边与它相邻的格子,“D”表示移动到当前格子下面与它相邻的格子。例如,上图中对于路径p1,有w(P1) = "RD";而对于另一条路径p2,有w(P2) = "DR"。

同时,将每条合法路径 P 经过的每个格子上填入的数字依次连接后,会得到一个长度为n + m − 1的 01 字符串,记为 s(P)。例如,如果我们在格子(0,0)和(1,0)上填入数字0,在格子(0,1)和(1,1)上填入数字 1(见上图红色数字)。那么对于路径p1,我们可以得到s(P1) = "011",对于路径p2,有s(P2) = "001"。

游戏要求小 D 找到一种填数字 0、1 的方法,使得对于两条路径p1,P2,如果w(P1) >w(P2),那么必须s(P1) ≤ s(P2)。我们说字符串 a 比字符串 b 小,当且仅当字符串 a 的字典序小于字符串 b 的字典序,字典序的定义详见第一题。但是仅仅是找一种方法无法满足小 D 的好奇心,小 D 更想知道这个游戏有多少种玩法,也就是说,有多少种填数字的方法满足游戏的要求?

小 D 能力有限,希望你帮助他解决这个问题,即有多少种填 0、1 的方法能满足题目要求。由于答案可能很大,你需要输出答案对109 + 7取模的结果。

【输入格式】

输入文件名为 game.in。

输入文件共一行,包含两个正整数 n、m,由一个空格分隔,表示矩形的大小。其中 n 表示矩形表格的行数,m 表示矩形表格的列数。

【输出格式】

输出文件名为 game.out。

输出共一行,包含一个正整数,表示有多少种填 0、1 的方法能满足游戏的要求。

注意:输出答案对 10^9+7 取模的结果。

【输入输出样例 1】

【样例解释】

对于2 × 2棋盘,有上图所示的 12 种填数方法满足要求。

【输入输出样例 2】

【输入输出样例 3】

【数据规模与约定】

参考答案:```#includeusing namespace std;#define ll long long#define mod 1000000007int n, m;ll f[55][55][55][55], sum[55][55][55];int main()cin >> n >> m;f[0][0][0][0] = 1;for (int i = 0; i <= n; i++){for (int j = 0; j <= m; j++){for (int k = 0; k <= i; k++){for (int l = 0; l <= j; l++){if (i == 0 && j == 0) continue;if (i == 0){f[i][j][k][l] = (f[i][j][k][l] + f[i][j - 1][k][l - 1]) % mod;if (l > 0) f[i][j][k][l] = (f[i][j][k][l] - f[i][j - 1][k][l - 2] + mod) % mod;}else if (j == 0){f[i][j][k][l] = (f[i][j][k][l] + f[i - 1][j][k - 1][l]) % mod;if (k > 0) f[i][j][k][l] = (f[i][j][k][l] - f[i - 1][j][k - 2][l] + mod) % mod;}else{f[i][j][k][l] = (f[i][j][k][l] + f[i - 1][j][k][l] + f[i][j - 1][k][l] - f[i - 1][j - 1][k - 1][l - 1] + mod) % mod;if (k > 0) f[i][j][k][l] = (f[i][j][k][l] - f[i - 1][j][k - 1][l] + mod) % mod;if (l > 0) f[i][j][k][l] = (f[i][j][k][l] - f[i][j - 1][k][l - 1] + mod) % mod;if (k > 0 && l > 0) f[i][j][k][l] = (f[i][j][k][l] + f[i - 1][j - 1][k - 1][l - 1] + mod) % mod;}if (i < n && j < m) sum[i][j][k] = (sum[i][j][k] + f[i][j][k][l]) % mod;}}}}ll ans = 0;for (int i = 0; i <= n; i++){for (int j = 0; j <= m; j++){for (int k = 0; k <= i; k++){ans = (ans + sum[i][j][k]) % mod;}}}cout << ans << endl;return 0;```


3、保卫王国

【问题描述】

Z 国有n座城市,n − 1条双向道路,每条双向道路连接两座城市,且任意两座城市都能通过若干条道路相互到达。

Z 国的国防部长小 Z 要在城市中驻扎军队。驻扎军队需要满足如下几个条件:

一座城市可以驻扎一支军队,也可以不驻扎军队。

由道路直接连接的两座城市中至少要有一座城市驻扎军队。

在城市里驻扎军队会产生花费,在编号为i的城市中驻扎军队的花费是pi。

小 Z 很快就规划出了一种驻扎军队的方案,使总花费最小。但是国王又给小 Z 提出了m个要求,每个要求规定了其中两座城市是否驻扎军队。小 Z 需要针对每个要求逐一给出回答。具体而言,如果国王提出的第j个要求能够满足上述驻扎条件(不需要考虑第 j 个要求之外的其它要求),则需要给出在此要求前提下驻扎军队的最小开销。如果国王提出的第j个要求无法满足,则需要输出-1 (1 ≤ j ≤ m)。现在请你来帮助小 Z。

【输入格式】

输入文件名为 defense.in。

第 1 行包含两个正整数n, m和一个字符串type,分别表示城市数、要求数和数据类型。type是一个由大写字母 A,B 或 C 和一个数字 1,2,3 组成的字符串。它可以帮助你获得部分分。你可能不需要用到这个参数。这个参数的含义在【数据规模与约定】中有具体的描述。

第2行n个整数pi,表示编号i的城市中驻扎军队的花费。

接下来n − 1行,每行两个正整数u, v,表示有一条u到v的双向道路。

接下来m行,第j行四个整数a, x, b, y(a ≠ b),表示第j个要求是在城市a驻扎x支军队,在城市b驻扎y支军队。其中,x 、 y 的取值只有 0 或 1:若 x 为 0,表示城市 a 不得驻扎军队,若 x 为 1,表示城市 a 必须驻扎军队;若 y 为 0,表示城市 b 不得驻扎军队,若 y 为 1,表示城市 b 必须驻扎军队。

输入文件中每一行相邻的两个数据之间均用一个空格分隔。

【输出格式】

输出文件名为 defense.out。

输出共m行,每行包含 1 个整数,第j行表示在满足国王第j个要求时的最小开销,如果无法满足国王的第j个要求,则该行输出-1。

【输入输出样例 1】

【样例解释】

对于第一个要求,在 4 号和 5 号城市驻扎军队时开销最小。

对于第二个要求,在 1 号、2 号、3 号城市驻扎军队时开销最小。

第三个要求是无法满足的,因为在 1 号、5 号城市都不驻扎军队就意味着由道路直接连

接的两座城市中都没有驻扎军队。

【数据规模与约定】

对于 100%的数据,n, m ≤ 300000,1 ≤ pi ≤ 100000。

数据类型的含义:

A:城市i与城市i + 1直接相连。

B:任意城市与城市 1 的距离不超过 100(距离定义为最短路径上边的数量),即如果这棵树以 1 号城市为根,深度不超过 100。

C:在树的形态上无特殊约束。

1:询问时保证a = 1, x = 1,即要求在城市 1 驻军。对b, y没有限制。

2:询问时保证a, b是相邻的(由一条道路直接连通)

3:在询问上无特殊约束。

参考答案:根据题目描述,我们需要首先建立城市的树状结构,然后根据国王的要求逐一计算驻扎军队的最小开销。由于城市的数量可能很大,直接计算所有可能的驻扎方案是不现实的。因此,我们可以使用动态规划的思想,通过逐步更新驻扎军队的状态来找到最小开销。具体的解题思路如下:1. 根据输入的城市和道路信息,建立城市的树状结构。可以使用深度优先搜索(DFS)或广度优先搜索(BFS)来实现。2. 对于每个城市,我们可以定义两个状态:驻扎军队和不驻扎军队。对于每个状态,我们可以计算驻扎军队的最小开销。3. 对于每个要求,我们可以根据要求中的信息更新驻扎军队的状态。如果要求中指定了某座城市必须驻扎军队,则将该城市的状态设置为驻扎军队;如果指定了某座城市不得驻扎军队,则将该城市的状态设置为不驻扎军队。4. 对于更新后的状态,我们可以使用动态规划的思想,从根节点开始逐步更新每个城市的最小开销。具体地,对于每个城市,我们可以计算其驻扎军队的最小开销和不驻扎军队的最小开销,然后取两者中的较小值作为该城市的最小开销。5. 对于每个要求,我们可以根据更新后的状态计算驻扎军队的最小开销。如果要求中指定的状态无法满足,则输出-1;否则,输出驻扎军队的最小开销。需要注意的是,由于城市的数量可能很大,直接计算所有可能的驻扎方案是不现实的。因此,我们需要使用动态规划的思想来优化计算过程,降低时间复杂度。同时,我们还需要注意数据类型的限制,根据数据类型的不同,我们可以采用不同的算法或策略来解决问题。


喵呜刷题:让学习像火箭一样快速,快来微信扫码,体验免费刷题服务,开启你的学习加速器!

创作类型:
原创

本文链接:全国信息学奥林匹克联赛(NOIP2018)复赛 提高组 day2参考答案

版权声明:本站点所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明文章出处。
分享文章
share