NYOJ-999-师傅又被妖怪抓走了

ACM模版

描述

描述

题解

第一次做双BFS,有些生疏,有些想当然。一直以为最先搜索出来的就是最优的,可是对于双BFS而言,第一个BFS最先搜索出来的不一定是最优的,需要将第一个BFS搜索出来的所有结果都进行第二个BFS,从得到的答案中选取最优即可。

因为没有写过双BFS,所以一开始写的代码十分冗杂,不够简练,后参考标准的双BFS代码后改写了一下下……

挺不错的一道题,毕竟是我做的第一个双BFS,理解了这个算法的误区后,感觉题也不是那么复杂(事后诸葛亮)。

代码

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>

using namespace std;

#define MAXN 105
#define INF 0x3f3f3f3f

typedef struct 
{
    int x;
    int y;
    int step;
} path;

char map[MAXN][MAXN];
int n, m, t;

path Path;  //  孙猴子起点位置

int ans = INF;
int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};

//  检查是否可以到达
bool check(int x, int y)
{
    if (map[x][y] == 'X' || map[x][y] == 'E' || map[x][y] == 'D')
    {
        return false;
    }
    return true;
}

//  预处理
char getCharValue(char otype, char type)
{
    if ((type == 'D' && otype == 'e') || (type == 'E' && otype == 'd'))
    {
        return 'b';
    }
    return type == 'D' ? 'd' : 'e';
}

//  预处理,把能看到D的位置置为d,看到E的位置置为e,能看到两者的置为b
void setMap(int x, int y, char type)
{
    int i;
    for (i = x + 1; i < n && check(i, y); ++i)
    {
        map[i][y] = getCharValue(map[i][y], type);
    }
    for (i = x - 1; i >= 0 && check(i, y); --i)
    {
        map[i][y] = getCharValue(map[i][y], type);
    }
    for (i = y + 1; i < m && check(x, i); ++i)
    {
        map[x][i] = getCharValue(map[x][i], type);
    }
    for (i = y - 1; i >= 0 && check(x, i); --i)
    {
        map[x][i] = getCharValue(map[x][i], type);
    }
}

//  检查边界
bool isLegal(path p)
{
    if (p.x >= 0 && p.y >= 0 && p.x < n && p.y < m)
    {
        return true;
    }
    return false;
}

int bfs_(path startp, char type)
{
    queue<path> Qu;
    bool vis[MAXN][MAXN];
    path ptop, ptmp;
    memset (vis, false, sizeof(vis));
    vis[startp.x][startp.y] = true;
    Qu.push(startp);

    while (!Qu.empty())
    {
        ptop = Qu.front();
        Qu.pop();
        if ((type == 'd' && map[ptop.x][ptop.y] == 'e') || (type == 'e' && map[ptop.x][ptop.y] == 'd'))
        {
            return ptop.step;
        }
        for (int i = 0; i < 4; ++i)
        {
            ptmp.x = ptop.x + dir[i][0];
            ptmp.y = ptop.y + dir[i][1];
            ptmp.step = ptop.step + 1;
            if (isLegal(ptmp) && check(ptmp.x, ptmp.y) && !vis[ptmp.x][ptmp.y] && ptmp.step < ans)
            {
                vis[ptmp.x][ptmp.y] = true;
                Qu.push(ptmp);
            }
        }
    }
    return t + 1;
}

void bfs()
{
    queue<path> Qu;
    path ptop, ptmp;
    bool visited[MAXN][MAXN];
    ans = INF;
    memset(visited, false, sizeof(visited));
    Qu.push(Path);
    visited[Path.x][Path.y] = true;

    while (!Qu.empty())
    {
        ptop = Qu.front();
        Qu.pop();
        if (map[ptop.x][ptop.y] == 'b')
        {
            ans = min(ans, ptop.step);
        }
        else if (map[ptop.x][ptop.y] == 'e' || map[ptop.x][ptop.y] == 'd')
        {
            //  找到一个人,调用第二个bfs寻找第二个人
            int tmp = bfs_(ptop, map[ptop.x][ptop.y]);
            ans = min (ans, tmp);
        }
        for (int i = 0; i < 4; ++i)
        {
            ptmp.x = ptop.x + dir[i][0];
            ptmp.y = ptop.y + dir[i][1];
            ptmp.step = ptop.step + 1;
            if (isLegal(ptmp) && check(ptmp.x, ptmp.y) && !visited[ptmp.x][ptmp.y] && ptmp.step < ans)
            {
                visited[ptmp.x][ptmp.y] = true;
                Qu.push(ptmp);
            }
        }
    }
    if (ans <= t)
    {
        printf ("%d\n", ans);
    }
    else
    {
        printf ("-1\n");
    }
}


int main()
{
    int Case = 1;
    while (~scanf("%d%d%d", &n, &m, &t))
    {
        for (int i = 0; i < n; ++i)
        {
            scanf ("%s", map[i]);
            for (int j = 0; j < m; ++j)
            {
                if (map[i][j] == 'S')
                {
                    Path.x = i, Path.y = j, Path.step = 0;
                }
            }
        }
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < m; ++j)
            {
                if (map[i][j] == 'E')
                {
                    setMap(i, j, map[i][j]);
                }
                else if (map[i][j] == 'D')
                {
                    setMap(i, j, map[i][j]);
                }
            }
        }
        printf ("Case %d:\n", Case++);
        bfs();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
孪生素数是指两个素数之间的差值为2的素数对。通过筛选法可以找出给定素数范围内的所有孪生素数的组数。 在引用的代码中,使用了递归筛选法来解决孪生素数问题。该程序首先使用循环将素数的倍数标记为非素数,然后再遍历素数数组,找出相邻素数之间差值为2的素数对,并统计总数。 具体实现过程如下: 1. 定义一个数组a[N,用来标记数字是否为素数,其中N为素数范围的上限。 2. 初始化数组a,将0和1标记为非素数。 3. 输入要查询的孪生素数的个数n。 4. 循环n次,每次读入一个要查询的素数范围num。 5. 使用两层循环,外层循环从2遍历到num/2,内层循环从i的平方开始,将素数的倍数标记为非素数。 6. 再次循环遍历素数数组,找出相邻素数之间差值为2的素数对,并统计总数。 7. 输出总数。 至此,我们可以使用这个筛选法的程序来解决孪生素数问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [python用递归筛选法求N以内的孪生质数(孪生素数)](https://blog.csdn.net/weixin_39734646/article/details/110990629)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [NYOJ-26 孪生素数问题](https://blog.csdn.net/memoryofyck/article/details/52059096)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值