NBUT 1624 死胡同(可以用搜索,也可以不用)

这篇博客探讨了NBUT 1624题目的解决方案,即如何判断一个猪猪在死胡同中是否会标记所有格子。题目要求在猪猪每走k步后在其所在位置打标记,当走到死胡同的边界时会改变方向。作者分享了一种非搜索算法的思路,通过设置数组记录朝某一方向行走过的格子,如果再次走到已标记的格子,则判断为死循环并结束。文章提供了C语言实现的代码示例。

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

题目链接:https://ac.2333.moe/Problem/view.xhtml?id=1624
[1624] 死胡同
时间限制: 1000 ms 内存限制: 65535 K
问题描述
一个死胡同由排成一列的 n 个格子组成,编号从 1 到 n 。
实验室的“猪猪”一开始在1号格子,开始向前走,每步一格,并且每走 k 步会在当前的格子上打上记号(开始时,1号格子也有记号)。由于这是死胡同,每当“猪猪”走到最左或者最右的格子时,它会改变方向。好奇的“猪猪”在想: 如果我一直走,能否把所有格子都打上记号呢?

聪明的你一定知道答案!

Hint1:如果 n=6,k=2,位置变化为:1 -> 3 -> 5 -> 5 -> 3 -> 1 -> 3 -> 5 .... 显然,此时不能将所有格子打上标记。(如下图)

输入
多组输入数据(组数<=100)
每组数据一行,包含两个正整数 n 和 k。
(1 <= n <= 100000 , 1 <= k <= 100000)
输出
对于每组数据输出一行 YES 或者 NO 代表能否给所有格子打上标记。
样例输入

6 2
6 3

样例输出

NO
YES

提示

无

来源

2015苏州大学ACM-ICPC集训队选拔赛(1)

题目大意: 题目讲的很清楚,不过要注意 k 是可以大于n 的 因为这个 我RE了几发。这个 有人用了搜索写出来的,,我不是用搜索,所以我这里的代码跟搜索没多大关系。

我的思路就是 设置一个数组,比如是记录朝右行走过的点,那么如果你下次还是朝右走,而且这个点已经走过了,那说明已经进入死循环 可以退出了,这样可以减少很多的时间。

上代码:

#include <stdio.h>
#include <string.h>
#include <math.h>
int vis[100010],star[100010];       //定义一个访问过的数组,还有一个就是 朝右走的访问标记
int main()
{
    int n,m;        //点的个数,还有一次走几格
    while(~scanf("%d%d",&n,&m))
    {
        if ( n == 1 )       //如果n == 1  那么肯定可以全部访问
        {
             printf("YES\n");
             continue;
        }
        memset(vis,0,sizeof(vis));  //初始化
        memset(star,0,sizeof(star));
        int res = 1;
        int l = 1;
        vis[1] = 1;     //起始点在1,所以直接访问过,
        int flag = 1;
        while (1)
        {
            if (l < 1)  
            {
                flag = 1;
                l = 2 - l ;
            }
            if (l > n )         
            {
                flag = -1;
                l = 2 * n - l;      //这个可以自己计算,为何这样,,这边减了之后,依旧可能比1小的,所以下面有一个判断。
            }
            if (l < 1)
            {
                flag = 1;
                l = 2 - l ;
            }
            if (vis[l] != 1 )       //没访问过
            {
                vis[l] = 1;
                res ++;
            }
            if ( (star[l] == 1 && flag == 1) || (flag == -1 && l == 1) )        //如果一个方向上的点,走了第二次 说明进入死循环 可以退出
            { 
                break;
            }
            if ( flag == 1)     //记录朝右走过的点
            {
                star[l] = 1;
            }
            if ( res == n )
            {
                break;
            }
            if (flag == 1 )
            {
                l += m % (2 * n - 2);       // 2*n - 2  这个规律不难发现,我是画一下图,就知道了 就是一个循环,就是下次走到这个点,并且走的方向是相同的
                continue;
            }
            else if (flag == -1)
            {
                l -= m % (2 * n - 2);
                continue;
            }
            //printf("%d\n",l);
        }
        if (res == n )
        {
            printf("YES\n");
        }
        else if(res != n)
        {
            printf("NO\n");
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值