URAL 1250 Sea Burial 简单Floodfill

问这个人掉落的海域包含几个岛屿。

八方向相连为同一片海域,四方向相连为同一个岛屿。与边界相连的岛屿不算。

方法:在给定地图外面填充一圈".",从这个人掉落的地方开始进行floodfill,标出他所在的海域。

然后再从(0, 0)点进行一次floodfill,把之前标记的海域之外的东西全部清掉。

最后统计岛屿个数即可。

注意:坐标是反着的

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

using namespace std;

const int MAXN = 510;

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

struct Point
{
    int x, y;
    Point( int x = 0, int y = 0 ): x(x), y(y) { }
};

Point Q[MAXN * MAXN * 2];
char G[MAXN][MAXN];
bool vis[MAXN][MAXN];
int R, C, X, Y;

bool check( int x, int y, bool wh )
{
    if ( wh ) return x > 0 && x <= R && y > 0 && y <= C;
    else return x >= 0 && x <= R + 1 && y >= 0 && y <= C + 1;
}

void FloodFill( Point st, char ch1, char ch2, char ch3, int dir )
{
    int front = 0, rear = 0;
    bool wh = false;
    if ( dir == 8 ) wh = true;

    Q[rear++] = st;

    while ( front < rear )
    {
        Point p = Q[front];

        G[ p.x ][ p.y ] = ch3;
        vis[ p.x ][ p.y ] = true;
        //printf( "%d %d
", p.x, p.y );
        for ( int i = 0; i < dir; ++i )
        {
            int xx = p.x + dx[i];
            int yy = p.y + dy[i];
            //printf( "vis[%d][%d] = %d
", xx, yy, vis[xx][yy] );
            if ( check( xx, yy, wh ) && !vis[xx][yy] && ( G[xx][yy] == ch1 || G[xx][yy] == ch2 ) )
            {
                vis[xx][yy] = true;
                Q[rear++] = Point( xx, yy );
            }
        }

        ++front;
    }
    return;
}

int main()
{
    //freopen("s.txt", "w", stdout );
    while ( ~scanf( "%d%d%d%d", &C, &R, &Y, &X ) )
    {
        memset( G, '.', sizeof(G) );
        G[0][ C + 2 ] = '';
        for ( int i = 1; i <= R; ++i )
        {
            scanf( "%s", &G[i][1] );
            G[i][ C + 2 ] = '';
        }

        memset( vis, false, sizeof(vis) );
        FloodFill( Point( X, Y ), '.', '.', '*', 8 );
        memset( vis, false, sizeof(vis) );
        FloodFill( Point( 0, 0 ),   '.', '#', ' ', 4 );

        memset( vis, false, sizeof(vis) );
        int ans = 0;
        for ( int i = 1; i <= R; ++i )
        for ( int j = 1; j <= C; ++j )
        if ( G[i][j] == '#' )
        {
            ++ans;
            FloodFill( Point( i, j ), '#', '#', '$', 4 );
        }
        printf( "%d
", ans );
    }
    return 0;
}
原文地址:https://www.cnblogs.com/GBRgbr/p/3238805.html