提示 1: 从起点出发的可能步骤太多,但从终点出发,前一步是什么是完全确定的。
提示 2: 考虑对所有的
从
但如果考虑某一个
于是我们考虑从后往前推。
不妨设某一个时刻第一次出现
于是枚举另一个数
由于
有没有什么优化的空间呢?假设我们当前是
上面的过程如果直接递归可能到达
需要注意的是,有些对是无法达到的,因为这些对可能到达
实际上,上述过程类似于求最大公因数,而两个数的最大公因数也始终不变,因此
时间复杂度为
Python 做法如下——
def main():
def f(x, y):
if x == 0: return -1
return y // x + f(y % x, x)
n = II()
print(min(f(i, n) for i in range(1, n + 1) if math.gcd(i, n) == 1))
C++ 做法如下——
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
auto f = [&] (auto &self, int x, int y) -> int {
if (x == 0) return -1;
return y / x + self(self, y % x, x);
};
int n;
cin >> n;
int ans = n;
for (int i = 1; i <= n; i ++) {
if (gcd(i, n) == 1) {
ans = min(ans, f(f, i, n));
}
}
cout << ans;
return 0;
}