专栏文章

题解:P2250 二面体群

P2250题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mip335mt
此快照首次捕获于
2025/12/03 05:22
3 个月前
此快照最后确认于
2025/12/03 05:22
3 个月前
查看原文

思路

设这一圈 nn 个数从小到大的方向为 tt,其中方向为顺时针时 t=1t=1,逆时针时 t=1t=-1。 设 360°n\frac{360\degree}{n} 为一个单位。
分别分析 22 种操作:
  1. 将这 nn 个点顺时针旋转 aa 个单位,因为转 nn 个单位相当于没有转,所以可以把 aann 取模,即 r %= n;
  2. 将这 nn 个点沿 xx 轴翻转 bb 次,因为翻转 22 次相当于没有翻转,所以可以把 bb22 取模,即 b %= 2;。如果 b=1b=1,那么数的方向要改变,原本顺时针的要改为逆时针,原本逆时针的要改为顺时针。即 ttt \to -t
先将 tt11 改为 1-1 再顺时针旋转 aa 个单位,相当于先逆时针旋转 aa 个单位再将 tt11 改为 1-1,所以可以设一共相当于顺时针转了 ansans 个单位,每次进行操作 11 时,ansans+t×aans \to ans+t \times a,并且对 nn 取模。
最终再分类讨论,输出操作步数最少的方案,相对简单,就不详细讲述了,代码中有注释。
最后注意:若无需操作则什么都不输出。

代码

CPP
#include <iostream>
using namespace std;

int main() {
	int n, t = 1, ans = 0;
	cin >> n;
	string s;
	while (cin >> s) {
		int x = 0;
		for (int i = 1; i < s.size(); i++)
			x = x * 10 + s[i] - '0'; // 拼数字
		if (s[0] == 'r') ans = (ans + t * x) % n; // 计算 ans
		else if (x & 1) t = -t; // 改变方向
	}
	ans = (ans + n) % n; // 取模
    // 分类讨论
	if (~t) { // t=1 的情况
		if (n - ans + 2 < ans) printf("m1 r%d m1", n - ans);
		else if (ans) printf("r%d", ans); // 如果 ans = 0 则不输出
	} else { // t=-1 的情况
        // 先转后翻,步数为 ans;先翻后转,步数为 n - ans
		if (n - ans < ans) printf("m1 r%d", n - ans);
		else printf("r%d m1", ans);
	}
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...