Acwing 红与黑 献给阿尔吉侬的花束(bfs与dfs新技巧)

9 篇文章 0 订阅
3 篇文章 0 订阅
思路

首先将图中所有的点,都声明为题目的“不可到底”的点,这样在bfs或者dfs判断条件时候,判断走过的点,越界和不可走的点三者就可以合为一个条件,极大了减少了判断的复杂性

Acwing 1113.红与黑
//bfs
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;


typedef pair<int , int > PII;

int dx[] ={-1, 0, 1, 0}, dy[] ={0,1,0,-1};

const int N = 50;

char g[N][N];

void bfs(PII start){
    
    int cnt = 1;
    
    queue<PII> q;
    
    q.push(start);

    while(!q.empty()){
    
    PII t = q.front();
    
    q.pop();
    
    for(int i = 0; i < 4; i++){
        int x = t.first + dx[i];
        int y = t.second + dy[i];
        if(g[x][y] == '#') continue;//此处判断越界、过墙和已经走过三种条件
        else if(g[x][y] == '.'){
            q.push({x,y});
            cnt++;
            g[x][y] = '#';//!!!!!尤其注意这里要将已经包含的点也给改为‘#’,否则会出现重复记录的情况
        }
        
        }
    } 

    cout << cnt << endl;
    
    return ;
}

int main(){
    int w, h;
    PII start;
    while(cin >> w >> h, w || h){
        memset(g,'#',sizeof g);//将g全部声明为红色瓷砖
        for(int i = 1; i <= h; i++){//从1开始输入直接避免了边界问题
            for(int j = 1; j <=w; j ++){
                cin >> g[i][j];
                if(g[i][j] == '@'){
                    start.first = i, start.second = j;
                }
            }
        }
        bfs(start);
    }
    return 0;
}
//dfs
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>

using namespace std;


typedef pair<int , int > PII;

int dx[] ={-1, 0, 1, 0}, dy[] ={0,1,0,-1};

const int N = 50;

char g[N][N];

int dfs(int a, int b){
    int cnt = 1;
    g[a][b] = '#';
    for(int i = 0; i < 4; i++){
        int x = a + dx[i];
        int y = b + dy[i];
        if(g[x][y] == '#') continue;//此处不仅判断红色瓷块还判断边界
        else {
            cnt += dfs(x,y);
        }
    }    
    return cnt;
}

int main(){
    int w, h,x,y;
    while(cin >> w >> h, w || h){
        memset(g,'#',sizeof g);
        for(int i = 1; i <= h; i++){//从1开始输入直接避免了边界问题
            for(int j = 1; j <=w; j ++){
                cin >> g[i][j];
                if(g[i][j] == '@'){
                    x = i, y = j;
                }
            }
        }
        int cnt = dfs(x,y);
        cout << cnt << endl;
    }
    return 0;
}

主要的用到的算法是 洪水灌溉算法,也就寻找最大连通快,flood fill算法
dfs代码简单,但是容易爆栈,在栈内存有1MB情况下容易爆,考试要记得注意栈内存

Acwing 献给阿尔吉侬的花束
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>

using namespace std;

typedef pair<int , int> PII;

const int N = 250;

char g[N][N];//存地图
int dist[N][N];//存距离


int dx[]={-1,0,1,0},dy[] = {0,1,0,-1};

void bfs(PII start){
    queue<PII>q;
    q.push(start);
    while(!q.empty()){
        PII t = q.front();
        q.pop();
        for(int i = 0 ; i < 4; i++){
            int x = t.first + dx[i];
            int y = t.second + dy[i];
            if(g[x][y] == '#') continue;
            if(g[x][y] =='.'){
                dist[x][y] = dist[t.first][t.second] + 1;
                g[x][y] = '#';//表示已经走过的路就变成了墙,不可以再往回走
                q.push({x,y});
            }
            else if(g[x][y] == 'E'){
                cout << dist[t.first][t.second] + 1 << endl;
                return ;
            }
        }
        g[t.first][t.second] = '#';
    }
    cout <<"oop!" << endl;
    return ;
}

int main(){
    int t,r,c;cin >> t;
    
    while(t--){
        
        memset(g,'#',sizeof g);
        memset(dist, 0,sizeof dist);
        
        cin >> r >> c;
        
        PII start;
        
        for(int i = 1; i <= r; i++)
        for(int j = 1; j <= c; j++)//从1开始减少了越界处理
        {
            cin >> g[i][j];
            if(g[i][j] == 'S')
            start.first = i,start.second = j;
        }
        bfs(start);
    }
           return 0;
}

此题思路与上一题类似

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值