Hint
Just to make it clearer, notice that this sample input corresponds to the following picture of the sky.
Notice that this sample output corresponds to the following picture.

Notice that this sample output corresponds to the following picture.

/**
poj 1175 #BFS
BFS出每个云团,问题在于处理两个云团是否相同。
处理方法是将每个云团映射到[0,0] 到[n,m]的矩阵中,然后就可以旋转或对称操作之后来比较了。
*/
#include <stdio.h>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;
#define N 555
#define M 111
#define INF 55555
char mat[M][M];
struct Point
{
int x,y;
Point(int a = 0,int b = 0)
{
x = a;
y = b;
}
};
bool cmp(Point a,Point b)
{
if(a.x == b.x)
return a.y < b.y;
return a.x < b.x;
}
struct node
{
int m,n,x,y;
vector<Point> vec;
void draw(char c)
{
int len = vec.size();
for(int i = 0; i < len; ++i)
mat[x+vec[i].x][y+vec[i].y] = c;
}
void push(vector<Point> ve)
{
int minx,miny,maxx,maxy;
minx = miny = INF;
maxx = maxy = -1;
int len = ve.size(),i;
for(i = 0; i < len; ++i)
{
minx = min(minx,ve[i].x);
miny = min(miny,ve[i].y);
maxx = max(maxx,ve[i].x);
maxy = max(maxy,ve[i].y);
}
n = maxx - minx + 1;
m = maxy - miny + 1;
x = minx;
y = miny;
for(i = 0; i < len; ++i)
vec.push_back(Point(ve[i].x-x,ve[i].y-y));
sort(vec.begin(),vec.end(),cmp);
}
void rotate()
{
int i,t,len = vec.size();
for(i = 0; i < len; ++i)
{
t = vec[i].y;
vec[i].y = n - vec[i].x - 1;
vec[i].x = t;
}
swap(m,n);
sort(vec.begin(),vec.end(),cmp);
}
void reservey()
{
int i,len = vec.size();
for(i = 0; i < len; ++i)
{
vec[i].x = n - vec[i].x - 1;
}
sort(vec.begin(),vec.end(),cmp);
}
void reservex()
{
int i,len = vec.size();
for(i = 0; i < len; ++i)
vec[i].y = m - vec[i].y - 1;
sort(vec.begin(),vec.end(),cmp);
}
}c[N];
bool same(node t,node p)
{
if(t.m == p.m && t.n == p.n && t.vec.size() == p.vec.size())
{
int i,len = t.vec.size();
for(i = 0; i < len && t.vec[i].x == p.vec[i].x && t.vec[i].y == p.vec[i].y; ++i);
return i == len;
}
return 0;
}
bool similars(node t,node p)
{
node pt;
if(t.m != p.m & t.n != p.n && t.m != p.n && t.n != p.m)
return 0;
for(int i = 0; i < 4; ++i)
{
if(same(t,p))
return 1;
pt = p;
pt.reservey();
if(same(t,pt))
return 1;
pt = p;
pt.reservex();
if(same(t,pt))
return 1;
p.rotate();
}
return 0;
}
int move[][2] = {0,1, 1,0, 0,-1, -1,0, 1,-1, 1,1, -1,1, -1,-1};
int n,m;
bool ok(int x,int y)
{
return x >= 0 && x < n && y >= 0 && y < m && mat[x][y] == '1';
}
vector<Point> bfs(int x,int y)
{
vector<Point> vv;
Point p(x,y),pt;
queue<Point> que;
int i;
que.push(p);
vv.push_back(p);
mat[x][y] = '0';
while(!que.empty())
{
p = que.front();
que.pop();
for(i = 0; i < 8; ++i)
{
pt = Point(p.x+move[i][0],p.y+move[i][1]);
if(ok(pt.x,pt.y))
{
que.push(pt);
vv.push_back(pt);
mat[pt.x][pt.y] = '0';
}
}
}
return vv;
}
int vis[N];
int main()
{
scanf("%d%d",&m,&n);
int i,j,k = 0;
for(i = 0; i < n; ++i)
scanf("%s",mat[i]);
for(i = 0; i < n; ++i)
for(j = 0; j < m; ++j)
if(mat[i][j] =='1')
c[k++].push(bfs(i,j));
char ch = 'a';
for(i = 0; i < k; ++i)
{
if(vis[i])
continue;
vis[i] = 1;
c[i].draw(ch);
for(j = i + 1; j < k; ++j)
if(!vis[j] && similars(c[i],c[j]))
{
c[j].draw(ch);
vis[j] = 1;
}
++ch;
}
for(i = 0; i < n; ++i)
printf("%s\n",mat[i]);
return 0;
}