[CCPC 2024 重庆站] 骰子 的题解
记住只在没有思路时使用题解,不要从它复制粘贴代码。请尊重题目和题解的作者。
在解题之前提交题解的代码会导致封禁。
在解题之前提交题解的代码会导致封禁。
作者:
概述
本题要求在 网格上通过滚动骰子并选择性记录底面数字,最大化所有记录数字的总和。核心解法是利用构造性证明,当
时,可使骰子经过每个格子时底面均为
,因此答案为
。
分析
核心观察
只要存在一种滚动路径,使得骰子访问每个格子时底面数字都是 ,就能让所有格子都写下最大值
。由于每次可以在经过格子时选择不写数字,只需关注如何通过滚动控制底面为
。
思路
构造一个局部操作:在 的方块中,从左上角开始,经过“下、右、上”三次滚动后,骰子到达右上角,并且底面恢复为
。具体地,设当前位置
已经写下
,执行:
- 向前(向下)滚到
,此时
转到后面;
- 向右滚到
,
仍在后面;
- 向后(向上)滚到
,
转到下面。 这样就在
写下了
。利用这个操作,可以借助下一行逐列向右推进,直到当前行的最后一列。
当到达行末 时,使用对称操作将骰子转到下一行并使
落在
:
- 向左滚到
,
转到右面;
- 向前(向下)滚到
,
仍在右面;
- 向右滚到
,
转到下面。 这样就在
写下了
。之后在下一行再反向(向左)推进,同样可逐格写下
。
对于最后一行(),可以借助上一行完成类似操作,只需将“向下”改为“向上”即可。由于网格尺寸至少为
,上述构造始终有效,能覆盖所有格子。
具体示例
以 网格为例:
- 初始在
,底面为
,写下
。
- 向下滚到
,不写数字;向右滚到
,不写数字;向上滚到
,底面为
,写下
。
- 再从
利用向下、向左、向上(需借助下一行)到达
,写下
。 最终四个格子均为
,总和
。
算法步骤
- 读取网格尺寸
n和m。 - 根据构造性证明,最大总和为所有格子都写下
,即
,直接输出该整数。
复杂度分析
- 时间:
- 空间:
实现注意事项
- 输入保证
,
最大为
,
约为
,在
int范围内。 - 直接输出计算结果,无需模拟骰子滚动。
- 注意使用
long long并非必须,但为了代码健壮性也可使用。
源代码
#include <iostream>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
cout << 6 * n * m << endl;
return 0;
}
n, m = map(int, input().split())
print(6 * n * m)
评论