1 条题解
-
1
#include <iostream> #include <string> using namespace std; // 定义结构体,存储每个玩具小人的朝向和职业 struct toy { int w; // 朝向:0表示朝内,1表示朝外 string name; // 职业名称 } p[100005]; // 数组,最多存储100005个玩具小人 int main() { int n, m; // n:玩具小人总数,m:指令条数 int index = 1; // 当前所在玩具小人的下标,初始为第1个 int c, g; // c:指令类型(0左数/1右数),g:数的个数 // 输入玩具小人总数和指令条数 cin >> n >> m; // 按逆时针顺序输入每个玩具小人的朝向和职业 for (int i = 1; i <= n; i++) { cin >> p[i].w >> p[i].name; } // 逐条执行指令 for (int i = 1; i <= m; i++) { cin >> c >> g; // 读入当前指令:c是方向,g是数的个数 /* 核心逻辑判断: 玩具朝内(0):左数=顺时针,右数=逆时针 玩具朝外(1):左数=逆时针,右数=顺时针 指令类型c: c=0:左数s个 c=1:右数s个 我们可以通过判断 c + 当前朝向 是否为1 来决定移动方向: 若 c + p[index].w == 1 → 表示移动方向是顺时针(数组下标增加) 否则 → 表示移动方向是逆时针(数组下标减少) */ if (c + p[index].w == 1) { // 顺时针移动:下标增加,取模防止越界 index = (index + g) % n; } else { // 逆时针移动:下标减少,加上n再取模保证非负 index = (index - g + n) % n; } // 取模后下标为0的情况,对应最后一个玩具小人(编号n) if (index == 0) { index = n; } } // 输出最终所在玩具小人的职业 cout << p[index].name; return 0; }
关键逻辑说明
-
为什么用
c + p[index].w == 1判断方向?- 朝内(0)的玩具:
- 左数(0)→ 顺时针 →
0 + 0 = 0,不满足条件 → 走逆时针(减) - 右数(1)→ 逆时针 →
1 + 0 = 1,满足条件 → 走顺时针(加)
- 左数(0)→ 顺时针 →
- 朝外(1)的玩具:
- 左数(0)→ 逆时针 →
0 + 1 = 1,满足条件 → 走顺时针(加) - 右数(1)→ 顺时针 →
1 + 1 = 2,不满足条件 → 走逆时针(减) 这个判断正好把“指令方向”和“朝向”的影响统一成了两种移动方式。
- 左数(0)→ 逆时针 →
- 朝内(0)的玩具:
-
为什么要处理
index == 0? 因为% n的结果范围是[0, n-1],而我们的数组下标是[1, n]。当index取模为0时,实际对应的是第n个玩具小人,所以要手动修正。
-
- 1
信息
- ID
- 2009
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- 递交数
- 14
- 已通过
- 5
- 上传者
粤公网安备44195502000195号