您的位置:首页 > 其它

HDU1241 Oil Deposits

2015-09-04 09:21 246 查看
题目地址: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

;
bool vis

;
// 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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: