#1310 : 岛屿
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
给你一张某一海域卫星照片,你需要统计:
1. 照片中海岛的数目
2. 照片中面积不同的海岛数目
3. 照片中形状不同的海岛数目
其中海域的照片如下,"."表示海洋,"#"表示陆地。在"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。
.####.. .....#. ####.#. .....#. ..##.#.
上图所示的照片中一共有4座岛屿;其中3座面积为4,一座面积为2,所以不同面积的岛屿数目是2;有两座形状都是"####",所以形状不同的岛屿数目为3。
输入
第一行包含两个整数:N 和 M,(1 ≤ N, M ≤ 50),表示照片的行数和列数。
以下一个 N * M 的矩阵,表示表示海域的照片。
输出
输出3个整数,依次是照片中海岛的数目、面积不同的海岛数目和形状不同的海岛数目。
- 样例输入
-
5 7.####.. .....#. ####.#. .....#. ..##.#.
样例输出 -
4 2 3
此处给出一个dfs技巧,在dfs的同时用一个string记录dfs时各个方向的搜索结果,那么形状相同的岛屿这个字符串应该是一样的,详见代码
#include#include #include #include #include #include #include #include #include using namespace std;#define rep(i,a,n) for (int i=a;i =a;i--)#define pb push_back#define fi first#define se secondtypedef vector VI;typedef long long ll;typedef pair PII;const int inf=0x3fffffff;const ll mod=1000000007;const int maxn=50+10;int dx[]={ 1,0,-1,0},dy[]={ 0,1,0,-1};char s[maxn][maxn];int vis[maxn][maxn];int ans=0;int n,m;string ss;int num;set s1;set s2;void dfs(int x,int y){ vis[x][y]=1; num++; rep(i,0,4) { int x1=x+dx[i],y1=y+dy[i]; if(x1<1||x1>n||y1<1||y1>m) { ss+='0'; continue; } if(s[x1][y1]=='#') { if(!vis[x1][y1]) { dfs(x1,y1); ss+='1'+i; } //else ss+='0'; 这句话加上也是可以的 } else ss+='0'; }}int main(){ scanf("%d%d",&n,&m); rep(i,1,n+1) scanf("%s",s[i]+1); int cnt=0; rep(i,1,n+1) rep(j,1,m+1) { if(s[i][j]=='#'&&!vis[i][j]) { cnt++; ss=""; num=0; dfs(i,j); s1.insert(num); s2.insert(ss); } } printf("%d %d %d\n",cnt,(int)s1.size(),(int)s2.size()); return 0;}