魔法少女小莹莹——SDUT

博客描述了小莹莹被困由 n 个石柱围成的迷宫,起始在 1 号石柱,每次可顺时针飞跃 a 或 b 距离,需到达第 m 个有传送门的石柱逃脱。给出输入输出格式及示例,要求判断能否逃脱并输出最少魔法使用次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem Description
小莹莹被困在了一个由 n 个石柱围成一圈组成的迷宫里,也就是 1, 2, 3, … n, 1, 2, 3, …. 这样一直循环。

她起始位置是 1,每次只能沿着顺时针方向选择飞跃 a 或者 b 距离的魔法,也就是从当前石柱 i 飞往 i+a 石柱或者 i+b 石柱。
第 m 个石柱有传送门,她只有到达第 m 个石柱,才能从这个迷宫逃脱出去。
问你小莹莹能否能顺利的逃离迷宫,如果不能输出 “NO”.
如果能输出 “YES”,同时问你小莹莹最少需要使用几次魔法?

Input
第一行输入正整数 T 代表有 T 组测试数据。
对于每一组测试数据:
第一行输入由空格隔开的 n, m 代表石柱的数量和所需到达的石柱。
第二行输入由空格隔开的 a, b 代表两个魔法,一个可以飞跃 a 距离,一个可以飞跃 b 距离。
( 1 <= n <= 1e5, 0 <= a, b < n, 1 <= m <= n, T 组数据 n 的和 <= 5e6 )

Output
如果小莹莹顺利逃离迷宫:
第一行输出:”YES”
第二行输出:小莹莹最少使用魔法次数。
如果小莹莹无法逃离迷宫:
第一行输出:”NO”
答案不包含 “”。

Sample Input
3
8 6
2 3
4 3
4 3
4 4
2 2
Sample Output
YES
2
YES
2
NO

Hint
Source
Satw_zg

#include <bits/stdc++.h>
using namespace std;
int bfs(int a, int b, int c, int d, int e);
const int maxn = 100010;
int cnt[maxn];//每个点到初始位置要几步
bool vis[maxn];//标记该点有没有走过
int main()
{
    int t, n, m, a, b;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d", &n, &m);//n个柱子,要求到达M;
        scanf("%d%d", &a, &b);//每次可以跳跃的距离
        int k = bfs(1, m, a, b, n);//n个柱子从一号开始每次跳跃a,或者B,要求到达m
        if(k == -1)
        {
            printf("NO\n");
        }
        else
        {
            printf("YES\n%d\n", k);
        }
    }
    return 0;
}
int bfs(int a, int b, int c, int d, int e)
{
    memset(vis, 0, sizeof(vis));//先将标记数组初始化为0
    queue<int> q;//创建一个队列
    vis[a] = true;//将首位置标记为1
    cnt[a] = 0;//首位置到首位置的距离是0
    q.push(a);//将首号位置的坐标放进队列
    int s, k;
    while(!q.empty())
    {
        s = q.front();
        q.pop();
        if(s == b)//判断条件,如果跳跃到b点
        {
            return cnt[b];//返回cnt[b]的值;
        }
        k = (s + c)%e;//跳跃c
        if(k == 0)k = e;
        if(!vis[k])
        {
            q.push(k);
            vis[k] = true;
            cnt[k] = cnt[s] + 1;
        }
        k = (s + d)%e;//跳跃d
        if(k == 0)k = e;
        if(!vis[k])
        {
            q.push(k);
            vis[k] = true;
            cnt[k] = cnt[s] + 1;
        }
    }
    return -1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值