HDU1241 Oil Deposits

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1241

/* HDU1241 Oil Deposits http://acm.hdu.edu.cn/showproblem.php?pid=1241 二维并查集 坐标转换 (i j) -> (i * 列数 + j) */
#include <stdio.h>
#include <stdlib.h>
#include<iostream> 
#include<cstring> 
#include<queue> 
#include <set> 
using namespace std;  

#define N 105
int m,n; 

char mp[N][N];
bool vis[N][N];
// 8个相邻的方向
int fangxiang[8][2] = {
    {-1,-1},{-1,0},{-1,1},{0,1},
    {1,1},{1,0},{1,-1},{0,-1}};

int fa[N*N];

int find(int x)
{
    if(x == fa[x])
        return x;
    return fa[x] = find(fa[x]);
}

void mergexy(int x,int y)
{
    fa[y] = find(x);
}

bool isOk(int x , int y)
{
    if(x >= 0 && x < m && y >= 0 && y < n && mp[x][y] == '@' && !vis[x][y]) // 这里的判断
        return true;
    return false;
}

void op(int x ,int y)
{
    // 8 个方向都处理到
    vis[x][y] =  true; // 先设置为已经访问过
    for(int i = 0 ; i < 8 ; i ++)
    {
        int nextx = fangxiang[i][0] + x;
        int nexty = fangxiang[i][1] + y;
        if( isOk(nextx,nexty) )
        {
            int m1 = x * n + y ; // 这里乘以的是列数 刚开始弄成m了 WA好久 ...
            int m2 = nextx * n + nexty ;
            if(find(m1) != find(m2))
            {
                mergexy(m1,m2);
                op(nextx,nexty); // 递归
            }
        }
    }
}

int main()  
{  
    //freopen("in.txt","r",stdin);
    int i , j ;
    while(scanf("%d%d\n",&m,&n) != EOF)
    {
        if(m == 0)
            break;
        for(i = 0 ;i < m*n;i++)
            fa[i] = i ;
        for(i = 0 ; i < m ;i ++)
        {
            for(j = 0 ; j < n ; j++)
            {
                scanf("%c",&mp[i][j]); // 输入char字符
                //fa[i*m+j] = i*m+j;
                vis[i][j] = false;
            }
            getchar(); // 吸收回车符
        }

        for(i = 0;i < m ;i ++)
        {
            for(j = 0 ; j < n ; j++)
            {
                if(mp[i][j] == '@' && !vis[i][j] )
                {
                    op(i,j);
                }
            }
        }
        set<int> sfa;
        sfa.clear();
    /* for(i = 0 ; i < m ; i ++) { for(j = 0 ; j < n ; j++) { if(mp[i][j] == '@') { sfa.insert( find(i*m+j) ); } } }*/
        for(i = 0 ;i < m*n;i++)
        {
            int xx = i / n;
            int yy = i % n;
            if(mp[xx][yy] == '@')
            {
                sfa.insert(find(i));
            }
        }

        int len = sfa.size();
        printf("%d\n",len);
    }
    return 0;  

}  

你可能感兴趣的:(HDU1241 Oil Deposits)