Flood Fill和最短路模型

图遍历与最短路径算法的应用
本文介绍了FloodFill、BFS和DFS算法在处理池塘问题和城堡问题中的应用,以及如何利用这些算法寻找山峰和山谷。此外,还展示了如何在最短路径模型中解决武士寻找牛的问题。这些算法展示了图遍历和最短路径在解决实际问题中的重要性。

Flood Fill

池塘问题

DFS写法

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1010;
char g[N][N];
int n, m;

void dfs(int x, int y)
{
    g[x][y] = '.';

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

    for (int i = 0; i < 8; i ++ )
    {
        int a = x + dx[i], b = y + dy[i];
        if (g[a][b] == 'W')
        {
            dfs(a, b);
        }
    }
}

int main()
{
    scanf("%d %d", &n, &m);

    for (int i = 0; i < n; i ++ )
        cin >> g[i];

    int cnt = 0;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++ )
            if (g[i][j] == 'W')
            {
                dfs(i, j);
                cnt ++ ;
            }


    cout << cnt << endl;
    return 0;
}

BFS写法(手写队列)

#include <cstring>
#include <iostream>
#include <algorithm>

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 1010, M = N * N;

int n, m;
char g[N][N];
PII q[M];
bool st[N][N];

void bfs(int sx, int sy)
{
    int hh = 0, tt = 0;
    q[0] = {sx, sy};
    st[sx][sy] = true;

    while (hh <= tt)
    {
        PII t = q[hh ++ ];

        for (int i = t.x - 1; i <= t.x + 1; i ++ )
            for (int j = t.y - 1; j <= t.y + 1; j ++ )
            {
                if (i == t.x && j == t.y) continue;
                if (i < 0 || i >= n || j < 0 || j >= m) continue;
                if (g[i][j] == '.' || st[i][j]) continue;

                q[ ++ tt] = {i, j};
                st[i][j] = true;
            }
    }
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i ++ ) scanf("%s", g[i]);

    int cnt = 0;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++ )
            if (g[i][j] == 'W' && !st[i][j])
            {
                bfs(i, j);
                cnt ++ ;
            }

    printf("%d\n", cnt);

    return 0;
}

城堡问题

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

#define x first
#define y second

typedef pair<int, int> PII;

const int N = 55, M = N * N;
int n, m;
int g[N][N];
PII q[M];
bool st[N][N];

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

int bfs(int sx, int sy)
{
    int hh = 0, tt = 0;
    int area = 0;
    
    q[0] = {sx, sy};
    st[sx][sy] = true;
    
    while (hh <= tt)
    {
        PII t = q[hh ++ ];
        area ++ ;
        
        for (int i = 0; i < 4; i ++ )
        {
            int a = t.x + dx[i], b = t.y + dy[i];
            if (a < 0 || a >= n || b < 0 || b >= m) continue;
            if (st[a][b]) continue;
            if (g[t.x][t.y] >> i & 1) continue;
            
            q[++ tt] = {a, b};
            st[a][b] = true;
            
        }
    }
    
    return area;
}

int main()
{
    cin >> n >> m;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++ )
            cin >> g[i][j];
    
    int cnt = 0, area = 0;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++)
            if (!st[i][j])
            {
                area = max(area, bfs(i, j));
                cnt ++ ;
            }
    
    cout << cnt << endl;
    cout << area << endl;
    
    return 0;
}

山峰和山谷

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

#define x first
#define y second

typedef pair<int, int> PII;

const int N = 1010, M = N * N;
int n;
int h[N][N];
PII q[M];
bool st[N][N];

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


int bfs(int sx, int sy, bool &has_higher, bool &has_lower)
{
    int hh = 0, tt = 0;
    
    q[0] = {sx, sy};
    st[sx][sy] = true;
    
    while (hh <= tt)
    {
        PII t = q[hh ++ ];
        
        for (int i = 0; i < 8; i ++ )
        {
            int a = t.x + dx[i], b = t.y + dy[i];
            if (a < 0 || a >= n || b < 0 || b >= n) continue;
            if (h[a][b] != h[t.x][t.y])
            {
                if (h[a][b] > h[t.x][t.y]) has_higher = true;
                else has_lower = true;
            }
            else if (!st[a][b])
            {
                q[++ tt] = {a, b};
                st[a][b] = true;
            }
        }
    }
}

int main()
{
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n; j ++ )
            scanf("%d", &h[i][j]);
    
    int peak = 0, valley = 0;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n; j ++)
            if (!st[i][j])
            {
                bool has_higher = false, has_lower = false;
                bfs(i, j, has_higher, has_lower);
                if (!has_higher) peak ++ ;
                if (!has_lower) valley ++ ;
            }
    printf("%d %d\n", peak, valley);
    
    return 0;
}

最短路模型

武士风度的牛

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 155, M = N * N;

#define x first
#define y second

typedef pair<int, int> PII;

int n, m;
PII q[M];
char g[N][N];
int dist[N][N];

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

int bfs()
{
    int sx, sy;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++ )
            if (g[i][j] == 'K')
            {
                sx = i;
                sy = j;
            }
    memset(dist, -1, sizeof dist);
    int hh = 0, tt = 0;
    q[0] = {sx, sy};
    dist[sx][sy] = 0;
    while (hh <= tt)
    {
        PII t = q[hh ++ ];
        
        for (int i = 0; i < 8; i ++ )
        {
            int a = t.x + dx[i], b = t.y + dy[i];
            
            if (a < 0 || a >= n || b < 0 || b >= m) continue;
            if (g[a][b] == '*') continue;
            if (dist[a][b] != -1) continue;
            
            if (g[a][b] == 'H') return dist[t.x][t.y] + 1;
            
            q[++ tt ] = {a, b};
            dist[a][b] = dist[t.x][t.y] + 1;
        }
    }
    
    return -1;
}

int main()
{
    cin >> m >> n;
    for (int i = 0; i < n; i ++ )
        cin >> g[i];
        
    cout << bfs() << endl;
    
    return 0;
}

抓住那头牛

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 100010;

int n, m;
int q[N];
int dist[N];
int dx[3] = {0};

int bfs()
{
    
    memset(dist, -1, sizeof dist);
    int hh = 0, tt = 0;
    q[0] = n;
    dist[n] = 0;
    while (hh <= tt)
    {
        auto t = q[hh ++ ];
        dx[0] = t - 1;
        dx[1] = t + 1;
        dx[2] = t * 2;
        
        for (int i = 0; i < 3; i ++ )
        {
            if (dx[i] < 0 || dx[i] >= N) continue;
            if (dist[dx[i]] != -1) continue;
            
            if (dx[i] == m) return dist[t] + 1;
            
            q[++ tt ] = dx[i];
            dist[dx[i]] = dist[t] + 1;
        }
    }
    return -1;
}

int main()
{
    cin >> n >> m;

    cout << bfs() << endl;
    
    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shirandexiaowo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值