1. 问题描述:
三个倒扣着的不透明小碗排成一排。随机挑选一个小碗,将一个小球置于碗中。然后进行 n 次操作,编号 1∼n。对于第 i 次操作:
如果 i mod 2 = 1,则操作内容为将位于中间的碗和位于左边的碗交换位置。
如果 i mod 2 = 0,则操作内容为将位于中间的碗和位于右边的碗交换位置。
我们不妨用 0,1,2 来表示左、中、右三个位置。
n 次操作全部完成以后,装有小球的碗位于位置 x,请你计算,所有操作开始前,装有小球的碗所在的初始位置。
输入格式
第一行,一个整数 n。第二行,一个整数 x。
输出格式
输出一个 0∼2 的整数,表示所有操作开始前,装有小球的碗所在的初始位置。
数据范围
前 6 个测试点满足 1 ≤ n ≤ 5;
所有测试点满足 1 ≤ n ≤ 2 × 10 ^ 9,0 ≤ x ≤ 2;
输入样例1:
4
2
输出样例1:
1
输入样例2:
1
1
输出样例2:
0
来源:https://www.acwing.com/problem/content/description/4414/
2. 思路分析:
分析题目可以知道 n 非常大,所以不能够直接模拟整个过程,我们可以找一下规律,由下图可知每 6 次操作为一个循环,6 次操作相当于恢复了未执行操作的状态,也即 6 为一个周期,所以 n 有效的操作次数为 n % 6,相当于是 n % 6 次操作之后得到了对应 x 的位置,所以我们可以使用循环从后往前重新执行相同的交换操作恢复数组中的状态即可:
3. 代码如下:
python:
class Solution:
def process(self):
n = int(input())
x = int(input())
# 6次为一个循环
n %= 6
a = [0, 0, 0]
a[x] = 1
# 重新执行上面的交换操作使得恢复原样
for i in range(n, 0, -1):
if i % 2 == 0:
a[1], a[2] = a[2], a[1]
else:
a[1], a[0] = a[0], a[1]
res = 0
for i in range(3):
if a[i] == 1:
res = i
print(res)
if __name__ == '__main__':
Solution().process()
go:
package main
import "fmt"
func main() {
var n, x int
fmt.Scan(&n, &x)
n %= 6
a := []int{0, 0, 0}
a[x] = 1
for i := n; i >= 1; i-- {
if i%2 == 0 {
a[1], a[2] = a[2], a[1]
} else {
a[1], a[0] = a[0], a[1]
}
}
res := 0
for i := 0; i < 3; i++ {
if a[i] == 1 {
res = i
}
}
fmt.Println(res)
}