啊哈算法---宝岛探险(深度优先搜索)着色法

/*着色法:在深度优化搜索里增加color的参数*/
#include<stdio.h>

int a[51][51];
int book[51][51];
int n, m, sum;
void dfs(int x, int y, int color)
{
    int k, tx, ty;
    //定义一个方向数组
    int next[4][2] = { { 0, 1 },//向右走
    { 1, 0 },//向下走
    { 0, -1 },//向左走
    { -1, 0 } };//向上走

    a[x][y] = color;//对a[x][y]格子染色

    //枚举四个方向
    for (k = 0; k<4; k++)
    {
        //计算下一步的坐标
        tx = x + next[k][0];
        ty = y + next[k][1];

        //判断是否越界
        if (tx<1 || tx>n || ty<1 || ty>m)
            continue;

        //判断是否是陆地
        if (a[tx][ty]>0 && book[tx][ty] == 0)
        {
            sum++;
            book[tx][ty] = 1; //标记这个点已经走过
            dfs(tx, ty, color);//开始尝试下一个点
        }
    }
    return;
}

int main()
{
    int i, j, startx, starty;
    scanf_s("%d %d %d %d", &n, &m, &startx, &starty);

    //读入地图
    for (i = 1; i <= n; i++)
        for (j = 1; j <= m; j++)
            scanf_s("%d", &a[i][j]); //读入地图 

    book[startx][starty] = 1;
    sum = 1;
    dfs(startx, starty, -1);//用-1表示对齐进行染色 

    //输出已经染色后的地图
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= m; j++)
        {
            printf("%3d", a[i][j]);//%3d中的3是c语言中的场宽
        }
        printf("\n");
    }
    getchar(); getchar();
    return 0;
}

 

 

如果想知道一副地图里有多少个独立的小岛又该怎么做呢?

so easy。只需要对地图上的每一个大于0的点都进行一遍深度优先搜索即可,因为等于0的点是海洋,小于0的点是已经被染色的小岛。

可以从(1,1)开始,一直枚举到(n,m),对每个点进行尝试染色。

/*着色法:在深度优化搜索里增加color的参数*/
#include<stdio.h>

int a[51][51];
int book[51][51];
int n, m, sum;
void dfs(int x, int y, int color)
{
    int k, tx, ty;
    //定义一个方向数组
    int next[4][2] = { { 0, 1 },//向右走
    { 1, 0 },//向下走
    { 0, -1 },//向左走
    { -1, 0 } };//向上走

    a[x][y] = color;//对a[x][y]格子染色

    //枚举四个方向
    for (k = 0; k<4; k++)
    {
        //计算下一步的坐标
        tx = x + next[k][0];
        ty = y + next[k][1];

        //判断是否越界
        if (tx<1 || tx>n || ty<1 || ty>m)
            continue;

        //判断是否是陆地
        if (a[tx][ty]>0 && book[tx][ty] == 0)
        {
            sum++;
            book[tx][ty] = 1; //标记这个点已经走过
            dfs(tx, ty, color);//开始尝试下一个点
        }
    }
    return;
}

int main()
{
    int i, j, num = 0;
    scanf_s("%d %d", &n, &m);

    //读入地图
    for (i = 1; i <= n; i++)
        for (j = 1; j <= m; j++)
            scanf_s("%d", &a[i][j]); //读入地图 

    //对每一个大于0的点尝试进行dfs染色
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= m; j++)
        {
            if (a[i][j] > 0)
            {
                num--;//小岛需要染色的颜色编号
                //每发现一个小岛应染以不同的颜色,因此每次要-1
                book[i][j] = 1;
                dfs(i, j, num);//对不同小岛按照num进行染色
            }
        }
    }
 

    //输出已经染色后的地图
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= m; j++)
        {
            printf("%3d", a[i][j]);//%3d中的3是c语言中的场宽
        }
        printf("\n");
    }

    //输出小岛的个数
    printf("有%d个小岛\n", -num);
    getchar(); getchar();
    return 0;
}

posted @ 2017-02-23 20:11  walanwalan  阅读(1523)  评论(0编辑  收藏  举报