1 条题解

  • 0
    @ 2025-8-24 22:41:20

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Nuyoah_awa
    事实证明,你没让我失望。

    搬运于2025-08-24 22:41:20,当前版本为作者最后更新于2023-04-02 21:37:49,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题目分析

    小明有一块电子表,准备调时间,M78 星云上一个小时 nn 分钟,小明每次可以往前调 11 分钟或 kk 分钟,求按照最优策略按键,从一个时间调到另一个时间最多要按多少次。

    题目分析

    小明从第 aa 分钟调到第 bb 分钟,假设 aabb 相差 cc 分钟(c<nc < n),我们可以把从第 aa 分钟调到第 bb 分钟看为从第 00 分钟调到第 cc 分钟,这样题意就简化为了从 00 开始,调到任意时间最少按多少次。

    我们可以把这道题视为一个图论题,我们将每个数 uuu+ku + ku+1u + 1 连边,问题就转化为了求 00 号节点到每个节点最短路的最大值,然后这道题就可以转换为 bfs\operatorname{bfs} 求解了。

    由于每个点到 00 的距离最大为 n1n - 1,就说明即使每回往后调 11,调 n1n - 1 次就可以调到所有时间了,所以时间复杂度是 O(n)\mathcal O(n) 的。

    code

    #include <iostream>
    #include <cstdio>
    #include <queue>
    
    using namespace std;
    
    const int N = 1e5 + 5;
    int n, k, t[N], cnt[N], x, y1, y2, ans;
    queue <int> q;
    
    int main()
    {
    	scanf("%d %d", &n, &k);
    	cnt[0] = true;
    	q.push(0);
    	while(!q.empty())
    	{
    		x = q.front();
    		q.pop();
    		ans = max(ans, t[x]);
    		y1 = (x + k) % n, y2 = (x + 1) % n;
    		if(!cnt[y1])
    		{
    			t[y1] = t[x] + 1, cnt[y1] = true;
    			q.push(y1);
    		}
    		if(!cnt[y2])
    		{
    			t[y2] = t[x] + 1, cnt[y2] = true;
    			q.push(y2);
    		}
    	}
    	printf("%d", ans);
    	return 0;
    }
    
    • 1

    信息

    ID
    5978
    时间
    3000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者