题解:P13577 [CCPC 2024 重庆站] 骰子

· · 题解

事实上,如果做这道题的时候手边能有个骰子就会简单很多(我就有好几个骰子,嘻嘻)。

思路

这道题要求一种感觉。
幸运的是,我很快就找到了这种“感觉”:n,m\geq2 时,所有 n\times m 个格子都可以在任意次操作后变成 6

证明

在这个证明中,我们无需考虑其他数字在骰子上的位置,只需要考虑 6 在哪个面即可。

我们可以将网格的右上角(骰子的初始位置)的坐标设为 (1,1)x 轴向右、y 轴向下建立坐标系。

初始,骰子在 (1,1) 位置,6 在下面。
接下来开始我们的操作。

  1. 骰子在 (1,1) 位置;
  2. 骰子向前转到 (2,1) 位置(第 2 行第 1 列),6 被转到后面;
  3. 骰子向右转到 (2,2) 位置,6 还在后面;
  4. 骰子向后转到 (1,2) 位置,6 被转到下面;
  5. (1,2) 位置写下 6

让我们来表示这个操作。

  1. 骰子在 (i,j) 位置(这个位置已经被写下 6;满足 1\leq i<n,\ 1\leq j<m)。
  2. (i,j+1) 位置写下 6

至此,我们完成了骰子向右转 1 格并写下 6 的操作。
总结:借助下一行不断完成向右 1 格并写下 6 的操作,最后填满网格。

现在我们还要来考虑 i=nj=m特殊情况

j=m 时,我们可以按照如下操作将位于 (i,m) 骰子转到下一行,并使 6 落到 (i+1,m) 这个格子上。

  1. 骰子在 (i,m) 位置(此时 6 在下面)。
  2. 骰子向左转到 (i,m-1) 位置,6 被转到右面;
  3. 骰子向前转到 (i+1,m-1) 位置,6 还在右面;
  4. 骰子向右转到 (i+1,m) 位置,6 被转到下面;
  5. (i+1,m) 位置写下 6

在第 i+1 行中,我们不能再将骰子每次向右移(因为本来就在最右边),但可以改为向左移。具体操作方法和向右移相似,只是每次操作方向对称,不再赘述。

结论

由以上证明,最终可以得出结论:当 n,m\geq2 时,所有格子都可以经过若干次操作后被写上 6,直接输出 n * m * 6

代码

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n, m; cin >> n >> m;
    cout << n * m * 6;
}