bfs题目+解释(基础题)

bfs广搜题目加部分解释
这里是我做过的一部分广搜的题目,写下是为了以后能够回顾。

第一题 Catch That Cow POJ 3278

题目链接
这道题的大致意思是给你两个数a,b。然后让你将a进行以下操作:1.a+1;2.a-1;3.x*a。问你a做上述操作最小几步能够变成b。
思路,一开始做这道题的时候我不知道它怎么会和bfs扯上关系的,然后问了一下旁边的大佬原来是将a变化出来的数字记录下来,然后一步一步去推,想出这一点,这道题就是bfs的入门题了。
具体代码如下:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int maxn = 200005;
int map[maxn];
int n, m;
int ans;
struct node{
    int x;
    int p;
} st;
bool ok(int x){
    if(x<0||x>100000)
        return false;
    else if(map[x])
        return false;
    else if(!map[x])
        return true;
}
void bfs(int x){
    queue<node> q;
    q.push(st);
    while(!q.empty()){
        node t=q.front();
        if(t.x==m){
            ans = t.p;
            break;
        }
        q.pop();
        node e;
        int fx = t.x + 1;
        int fy = t.x - 1;
        int fz = t.x * 2;
        if(ok(fx)){
            e.x = fx;
            e.p = t.p + 1;
            map[fx] = 1;
            q.push(e);
        }
        if(ok(fy)){
            e.x = fy;
            e.p = t.p + 1;
            map[fy] = 1;
            q.push(e);
        }
        if(ok(fz)){
            e.x = fz;
            e.p = t.p + 1;
            map[fz] = 1;
            q.push(e);
        }
    }
}
int main(){
    scanf("%d%d", &n, &m);
    st.x = n;
    st.p = 0;
    ans = 0;
    memset(map, 0, sizeof map);
    map[n] = 1;
    bfs(n);
    printf("%d\n", ans);
}

第二题 Dungeon Master POJ 2251

题目链接
这道题的大致意思就是给你一个一共有n层每层m*k大小的迷宫,入口在S处,出口在E处,每移动1格需要浪费,‘#’是不可以走的,‘.’是可以走的。问你是否能逃出,如果能逃出需要耗费多少时间。
这道题不同于我平时做的bfs题,平时做的bfs一般是2维的,这道题是三维,可是做法是一样的,只要将移动数组改为{{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}}就可以了,做法和二维一样。
具体代码如下:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 40;
char ah[maxn][maxn][maxn];
int map[maxn][maxn][maxn];
int l, r, c;
int ans;
int moved[10][5] = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}};
struct node{
    int x;
    int y;
    int z;
    int p;
}st;
bool ok(int x,int y,int z){
    if(x<1||x>l||y<1||y>r||z<1||z>c){
        return false;
    }
    else if(map[x][y][z]==0)
        return true;
    else if(map[x][y][z]==1)
        return false;
}
bool bfs(int x,int y,int z){
    queue<node> q;
    q.push(st);
    int flag = 0;
    while(!q.empty()){
        node t = q.front();
        q.pop();
        if(ah[t.x][t.y][t.z]=='E'){
            ans = t.p;
            return true;
        }
        for (int i = 0; i < 6;i++){
            int fx = t.x + moved[i][0];
            int fy = t.y + moved[i][1];
            int fz = t.z + moved[i][2];
            if(ok(fx,fy,fz)){
                node f;
                f.x = fx;
                f.y = fy;
                f.z = fz;
                f.p = t.p + 1;
                q.push(f);
                map[fx][fy][fz] = 1;
            }
        }
    }
    return false;
}
int main(){
    while(scanf("%d%d%d", &l, &r, &c)&&l&&r&&c)
    {
        for (int i = 1; i <= l;i++){
        for (int j = 1; j <= r;j++){
            scanf("%s", ah[i][j] + 1);
        }
    }
    
    for (int i = 1; i <= l;i++){
        for (int j = 1; j <= r;j++){
            for (int k = 1; k <= c;k++){
                if(ah[i][j][k]=='S'){
                    st.x = i;
                    st.y = j;
                    st.z = k;
                    st.p = 0;
                }
                else if(ah[i][j][k]=='.'||ah[i][j][k]=='E'){
                    map[i][j][k] = 0;
                }
                else if(ah[i][j][k]=='#')
                    map[i][j][k] = 1;
            }
        }
    }
    if(bfs(st.x, st.y, st.z))
        printf("Escaped in %d minute(s).\n", ans);
    else
        printf("Trapped!\n");
    }
}

第三题 Asteroids! HDU 1240

题目链接
这道题的大致意思和上面一题是差不多的,给你一个N层每层N*N大小的平面,然后给你个起点和终点,‘X’是不能走的,‘o’是可以走的。问你是否能从起点走到终点,如果能要走几步。
这道题和上一题基本是一模一样的,只是题面,输入,输出换了,做法是一模一样的,都是三维中用bfs搜索。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 15;
char sta[10];
char end1[10];
char map[maxn][maxn][maxn];
int dp[maxn][maxn][maxn];
int moved[10][5] = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}};
int n;int ans;
struct node{
    int x, y, z;
    int s;
}st,en;
bool ok(int x,int y,int z){
    if(x>=n||x<0||y>=n||y<0||z>=n||z<0)
        return false;
    else if(dp[x][y][z])
        return false;
    else
        return true;
}
bool bfs(){
    queue<node> q;
    q.push(st);
    while(!q.empty()){
        node t = q.front();
        q.pop();
        if(t.x==en.x&&t.y==en.y&&t.z==en.z){
            ans = t.s;
            return true;
        }
        for (int i = 0; i < 6;i++){
            int fx = t.x + moved[i][0];
            int fy = t.y + moved[i][1];
            int fz = t.z + moved[i][2];
            if(ok(fx,fy,fz)){
                node e;
                e.x = fx;
                e.y = fy;
                e.z = fz;
                e.s = t.s + 1;
                dp[fx][fy][fz] = 1;
                q.push(e);
            }
        }
    }
    return false;
}
int main(){
    while(~scanf("%s%d",sta,&n)){
        for (int i = 0;i<n;i++){
            for (int j = 0;j<n;j++){
                scanf("%s", map[i][j] );
            }
        }
        for (int i = 0;i<n;i++){
            for (int j = 0; j < n;j++){
                for (int k = 0; k < n;k++){
                    if(map[i][j][k]=='X')
                        dp[i][j][k] = 1;
                    else
                        dp[i][j][k] = 0;
                }
            }
        }
        scanf("%d%d%d", &st.z, &st.y, &st.x);
        dp[st.x][st.y][st.z] = 1;
        scanf("%d%d%d", &en.z, &en.y, &en.x);
        st.s = 0;
        ans = 0;
        scanf("%s", end1);
        if(bfs())
            printf("%d %d\n", n, ans);
        else
            printf("NO ROUTE\n");
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值