题目链接:AtCoder Beginner Contest 188 F.+1-1x2
大致题意
给定整数x, y. 可以执行三个操作: ①把x加1 ②把x减1 ③把x乘2
问: 最少多少步可以把x变成y
解题思路
考虑到把x变成某一个数字y:
- 如果x比y大, 那么只能通过执行y - x次 ②
- 如果此时y为偶数: 我们可以执行x - y次①, 或者是通过y / 2的情况进行③得到.
- 如果此时y为奇数: 同样可以执行x - y次①, 或者是通过(y - 1) / 2 或 (y + 1) / 2的情况进行③得到.
AC代码
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
using namespace std;
typedef long long ll;
const int N = 1E5 + 10;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll a[N], s[N];
set<ll> st;
int main()
{
int n; cin >> n;
rep(i, n) scanf("%lld", &a[i]);
for (int i = n; i >= 1; --i) s[i] = gcd(s[i + 1], a[i]);
rep(i, n - 1) st.insert(a[i] / gcd(a[i], s[i + 1]) * s[i + 1]);
ll res = 0;
for (auto& op : st) {
res = gcd(res, op);
}
cout << res << endl;
return 0;
}
考虑到情况3, 其实也是把当前奇数变成相邻偶数, 去考虑情况2