[2018蓝桥杯B组决赛] D-调手表
题解
当你第一次看到这个题的时候,你会想到什么算法呢?
当要求最小步数的时候,很显然,最快想到应该是 bfs,而非其它算法,这里需要注意一点的是,从时刻 m1 到 m2,我们需要求解的是时刻差,而与具体时刻是没有关系的,此时我们就可以从 0 开始,到其它任意时刻,是可以少一重循环的。
另外 bfs() 只需要做一次即可,即求出从 0 点到其它时刻的最小步数,再取 max 为该题的答案。
#include <iostream> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int N = 100010; int n, k, ans; int d[N]; void bfs() { int st = 0; memset(d, -1, sizeof(d)); queue <int> q; q.push(st); d[st] = 0; // 求最优解 while (!q.empty()) { int t = q.front(); q.pop(); for (int j = 1; j <= 2; ++j) { int tmp = t; if (j == 1) tmp = (tmp + 1) % n; if (j == 2) tmp = (tmp + k) % n; if (d[tmp] == -1) { q.push(tmp); d[tmp] = d[t] + 1; } } } } int main() { cin >> n >> k; bfs(); for (int i = 1; i < n; ++i) { ans = max(ans, d[i]); } cout << ans << endl; return 0; }