【POJ 3026】Borg Maze(BFS+Prime算法)

题目链接:http://poj.org/problem?id=3026

题意:

有一个迷宫,迷宫里面有一些外星人,你需要通过扫描迷宫来同化隐藏在迷宫中的外星人,迷宫里的S是起点,搜索的开始是由多个人组成的,搜索过程中,在外星人处或搜索开始的地方,该群体可能会分成两组或更多组。求同化所有外星人所需要的最小步数。

思路:

刚开始一直在纠结分组是啥意思,为嘛要分组,咋分组才能使成本最小,后来看了大佬的博客才知道这句没啥用,主要是为了把它抽象成最小生成树。

这题可以这样理解,一群外星人在一张地图当中,你有不小于外星人数量的人手,你要找到他们,并且你可以在找到外星人或出发时将人手分成任意两部分(这是不是就有点儿像最小生成树里的Prime算法)。

嗯 ,这样的话,主要问题就在于如何求两点之间的距离了,这类似于迷宫里求起点到终点的距离,因此就需要用bfs算法求迷宫里面两点之间的距离。下面可以结合代码走一遭。

噢   对,这道题里面还藏了一个自我感觉良好的坑,(据说做了这题的娃儿都被它成功坑到了,当然,我也没跑掉)输入迷宫的x,y后面还有些空格,不得不说出题人真的很淘气

My  Code:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<math.h>
#include<set>
using namespace std;
#define INF 1e9
typedef long long ll;
int dis[105][105],d[105],flag[105],n;
void Prime()///最小生成树
{
    memset(flag,0,sizeof(flag));
    for(int i =1; i <= n; i++)
        d[i] = dis[1][i];
    d[1] = 0;
    flag[1] = 1;
    int ans = 0;
    for(int i = 1; i < n; i++)
    {
        int minn = INF,k;
        for(int j = 1; j <= n; j++)
        {
            if(d[j] < minn && flag[j] == 0)
            {
                minn = d[j];
                k = j;
            }
        }
        flag[k] = 1;
        ans += d[k];
        for(int j = 1; j <= n; j++)
            d[j] = min(d[j],dis[k][j]);
    }
    printf("%d\n",ans);
}
struct point
{
    int x,y,step;
};
int vis[55][55],node[55][55],col,row;
///vis标记是否走过,node用来标记外星人A和起点S
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
char ch[55][55];
void bfs(int i,int j)///求出每两点之间的距离
{
    memset(vis,0,sizeof(vis));
    point start;
    start.x = i;
    start.y = j;
    start.step = 0;
    vis[start.x][start.y] = 1;
    point cur,nxt;
    queue<point> q;
    q.push(start);
    while(!q.empty())///遍历整个迷宫,求出起点到其他各点的距离
    {
        cur = q.front();
        q.pop();
        if(node[cur.x][cur.y]) dis[node[start.x][start.y]][node[cur.x][cur.y]] = cur.step;///碰到一个点,记录他们俩之间的距离
        for(int i = 0; i < 4; i++)
        {
            nxt.x = cur.x + dir[i][0];
            nxt.y = cur.y + dir[i][1];
            nxt.step = cur.step +1;
            if(nxt.x >= 0 &&nxt.x < row && nxt.y >= 0 && nxt.y < col && ch[nxt.x][nxt.y] != '#' && vis[nxt.x][nxt.y] == 0)
            {
                vis[nxt.x][nxt.y] = 1;
                q.push(nxt);
            }
        }
    }
    return;
}
int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        char s[10000];
        scanf("%d%d",&col,&row);
        gets(s);///注意输入行列后面还有空格,确保自己代码没问题但还是wa的看看是否加了这句
        memset(ch,'\0',sizeof(ch));
        memset(node,0,sizeof(node));
        int cunt = 1;
        for(int i = 0; i < row; i++)
        {
            getchar();///吃掉多余的换行符
            scanf("%[^\n]",ch[i]);
            for(int j =0; j < col; j++)
            {
                if(ch[i][j] == 'S' || ch[i][j] == 'A')
                    node[i][j] = cunt++;
            }
        }
        n = cunt -1;
        for(int i = 0; i < row; i++)
        {
            for(int j = 0; j < col; j++)
            {
                if(node[i][j]) bfs(i,j);///以点(i,j)为起点遍历整个迷宫
            }
        }
        Prime();
    }

    return 0;
}

 

全部评论

相关推荐

上周组里招人,我面了六个候选人,回来跟同事吃饭的时候聊起一个让我挺感慨的现象。前三个候选人,算法题写得都不错。第一道二分查找,五分钟之内给出解法,边界条件也处理得干净。第二道动态规划,状态转移方程写对了,空间复杂度也优化了一版。我翻他们的简历,力扣刷题量都在300以上。后三个呢,就有点参差不齐了。有的边界条件没处理好,有的直接说这道题没刷过能不能换个思路讲讲。其中有一个女生,我印象特别深——她拿到题之后没有马上写,而是先问我:“面试官,我能先跟你确认一下我对题目的理解吗?”然后她把自己的思路讲了一遍,虽然最后代码写得不是最优解,但整个沟通过程非常顺畅。这个女生的代码不是最优的,但当我问她“如果这里是线上环境,你会怎么设计’的时候,她给我讲了一套完整的方案——异常怎么处理、日志怎么打、怎么平滑发布。她对这是之前在实习的时候踩过的坑。”我在想LeetCode到底在筛选什么?我自己的经历可能有点代表性。我当年校招的时候,也是刷了三百多道题才敢去面试。那时候大家都刷,你不刷就过不了笔试关。后来工作了,前三年基本没再打开过力扣。真正干活的时候,没人让你写反转链表,也没人让你手撕红黑树。更多的是:这个接口为什么慢了、那个服务为什么OOM了、线上数据对不上了得排查一下。所以后来我当面试官,慢慢调整了自己的评判标准。算法题我还会出,但目的变了。我出算法题,不是想看你能不能背出最优解。而是想看你拿到一个陌生问题的时候,是怎么思考的。你会先理清题意吗?你会主动问边界条件吗?你想不出来的时候会怎么办?你写出来的代码,变量命名乱不乱、结构清不清楚?这些才是工作中真正用得到的能力。LeetCode是一个工具,不是目的。它帮你熟悉数据结构和常见算法思路,这没问题。但如果你刷了三百道题,却说不清楚自己的项目解决了什么问题、遇到了什么困难、你是怎么解决的,那这三百道题可能真的白刷了。所以还要不要刷LeetCode?要刷,但别只刷题。刷题的时候,多问自己几个为什么:为什么用这个数据结构?为什么这个解法比那个好?如果换个条件,解法还成立吗?把刷题当成锻炼思维的方式,而不是背答案的任务。毕竟面试官想看到的,从来不是一台背题机器,而是一个能解决问题的人。
AI时代还有必要刷lee...
点赞 评论 收藏
分享
zzzilik:没事的,才刚刚开始,后面会捞的,这个三天没人发起面试自动结束,但是面试官还是能看到简历,四月份主战场会慢慢捞
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务