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;
}
本文介绍了一种使用BFS算法处理二维矩阵中的云团,并通过旋转和平面对称操作比较不同云团的方法。针对每个独立的云团,算法将其标准化并映射到固定坐标系中进行比较。
512

被折叠的 条评论
为什么被折叠?



