您的位置:首页 > 其它

Educational Codeforces Round 5(C)(DFS+hash)

2016-01-12 18:36 435 查看
C. The Labyrinth

time limit per test
1 second

memory limit per test
256 megabytes

input
standard input

output
standard output

You are given a rectangular field of n × m cells. Each cell is either empty or impassable (contains an obstacle). Empty cells
are marked with '.', impassable cells are marked with '*'.
Let's call two empty cells adjacent if they share a side.

Let's call a connected component any non-extendible set of cells such that any two of them are connected by the path of adjacent cells. It is a typical well-known definition of a connected component.

For each impassable cell (x, y) imagine that it is an empty cell (all other cells remain unchanged) and find the size (the number
of cells) of the connected component which contains (x, y). You should do it for each impassable cell independently.

The answer should be printed as a matrix with n rows and m columns.
The j-th symbol of thei-th
row should be "." if the cell is empty at the start. Otherwise the j-th
symbol of the i-th row should contain the only digit —- the answer modulo 10.
The matrix should be printed without any spaces.

To make your output faster it is recommended to build the output as an array of n strings having length m and
print it as a sequence of lines. It will be much faster than writing character-by-character.

As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to use scanf/printf instead of cin/cout in
C++, prefer to useBufferedReader/PrintWriter instead of Scanner/System.out in Java.

Input

The first line contains two integers n, m (1 ≤ n, m ≤ 1000)
— the number of rows and columns in the field.

Each of the next n lines contains m symbols:
"." for empty cells, "*" for impassable cells.

Output

Print the answer as a matrix as described above. See the examples to precise the format of the output.

Sample test(s)

input
3 3
*.*
.*.
*.*


output
3.3
.5.
3.3


input
4 5
**..*
..***
.*.*.
*.*.*


output
46..3
..732
.6.4.
5.4.3


Note

In first example, if we imagine that the central cell is empty then it will be included to component of size 5 (cross). If any of the corner cell
will be empty then it will be included to component of size 3 (corner).

题意:简单来说就是求‘*’这个符号他周围有多少个联通的符号‘.’的个数

题解:

1.开始写DFS超时了,因为每次遇到‘*’都要去搜一次,那么改变一下思路,既然是求‘*’上下左右的‘.’联通块的个数,那么我们先将这些可以联通的‘.’作为一个相同的区域,用DFS跑一遍,计数的同时,保存他们的下标,最后使用数组记录下个数,这样就最多只需要遍历一遍图。

2.最后写完发现在求‘*’上下左右的联通块个数时可能会发生一个区域块重复加多次。那么我们需要对每个块进行标号hash,判断有没有重复加的情况,建议使用set判重,开始使用数组一直错误,原来开小了

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;
#define LL long long
#define N 1055
char g

;
char tmp

;
struct point
{
int x,y;
point(int _x,int _y):x(_x),y(_y){}
point(){}
};
struct clca
{
int val;
int st;
}answer

;
int vx[]={0,0,-1,1};
int vy[]={1,-1,0,0};
vector<point>eg;
int sum;
int n,m;
void dfs(int xx,int yy)
{
if(xx<0||yy<0||xx>=n||yy>=m||g[xx][yy]=='*')
{
return ;
}
g[xx][yy]='*';
eg.push_back(point(xx,yy));
sum++;
for(int i=0;i<4;i++)
{
int tx=xx+vx[i];
int ty=yy+vy[i];
dfs(tx,ty);
}
}
int main()
{
#ifdef CDZSC
freopen("i.txt","r",stdin);
#endif
while(~scanf("%d%d",&n,&m))
{
eg.clear();
int hassh=0;
for(int i=0;i<n;i++)
{
scanf("%s",g[i]);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
answer[i][j].val=0;
answer[i][j].st=0;
tmp[i][j]=g[i][j];
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(g[i][j]=='.')
{
++hassh;
sum=0;
dfs(i,j);
for(int k=0;k<eg.size();k++)
{
answer[eg[k].x][eg[k].y].val=sum;
answer[eg[k].x][eg[k].y].st=hassh;
}
eg.clear();
}
}
}

#ifdef CDZS
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
printf("%d ",answer[i][j].st);
}
puts("");
}
#endif

for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(tmp[i][j]=='*')
{
int num=1;
int xx,yy;
set<int>SET;
for(int k=0;k<4;k++)
{
xx=i+vx[k];
yy=j+vy[k];
if(xx<0||yy<0||xx>=n||yy>=m)
{
continue;
}
if(!SET.count(answer[xx][yy].st))
{
SET.insert(answer[xx][yy].st);
num+=answer[xx][yy].val;
}
}
printf("%c",char('0'+num%10));
}
else
{
printf(".");
}
}
puts("");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: