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.
![](https://i-blog.csdnimg.cn/blog_migrate/7a3a5c0e3be0e080d9deed49a6e75d1e.jpeg)
Notice that this sample output corresponds to the following picture.
![](https://i-blog.csdnimg.cn/blog_migrate/41569ae8cee083edfeca53dec8e8d6e3.jpeg)
/**
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;
}