题目链接:传送门
时间限制:
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解题思路:详细题解
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <queue>
#include <set>
#include <string>
#include <stack>
#include <algorithm>
#include <map>
#include <bitset>
using namespace std;
typedef long long ll;
const int N = 60;
const int M = 1000009;
const int INF = 0x3fffffff;
const int mod = 1e9+7;
const double Pi = acos(-1.0);
const double sm = 1e-9;
typedef pair<int,int>PA;
char data[N][N];
int vis[N][N],tot,r0,c0;
int x[] = { -1 , 0 , 1 , 0 };
int y[] = { 0 , -1 , 0 , 1 };
char re[] = {'l','u','r','d'};
vector<PA>st;
bool comp(const PA&a ,const PA&b ){
if(a.first==b.first) return a.second<b.second;
else return a.first<b.first;
}
void dfs( int r , int c )
{
++tot;
vis[r][c] = 1;
st.push_back(PA(r-r0,c-c0));
for( int i = 0 ; i < 4 ; ++i ){
int nr = r+x[i];
int nc = c+y[i];
if( data[nr][nc] != '#'||vis[nr][nc] != 0 ) continue;
dfs( nr , nc );
}
}
int main()
{
int n,m;
while( cin >> n >> m ){
memset( vis , 0 , sizeof(vis) );
memset( data , 0 , sizeof(data) );
for( int i = 1 ; i <= n ; ++i ){
cin >> data[i]+1;
}
map<vector<PA>,int>mp1;
map<int,int>mp2;
int cnt1=0;
for( int i = 1 ; i <= n ; ++i ){
for( int j = 1 ; j <= m ; ++j ){
if( data[i][j] == '#'&& !vis[i][j] ){
tot = 0; st.clear();
r0 = i,c0 = j;
dfs(i,j);
sort(st.begin(),st.end(),comp);
++cnt1;
++mp2[tot];
++mp1[st];
}
}
}
cout << cnt1 << " " << mp2.size() << " " << mp1.size() << endl;
}
return 0;
}