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
output
input
output
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判重,开始使用数组一直错误,原来开小了
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; }
相关文章推荐
- debug使用
- android 6.0 and sdk23, when used xx.so has text relocations.
- 160122_孙子兵法_始计
- cocos2dx之lua项目开发中MVC框架的简单应用
- 【转】理解 PHP 依赖注入 | Laravel IoC容器
- 查看一个文件是否支持64位 方法 ,[symbol(s) not found for architecture x86_64]相关
- 数字八
- POJ 3734 Blocks(矩阵优化+DP)
- ElasticSearch 概述
- C++的高级用法
- Mysql 启动慢查询日志 (不用重启)
- 图片比例转换算法
- Struts2与Spring整合
- 一个基于Matlab的简单Gui设计
- Facebook Hacker Cup 2016 Qualification Round 解题报告
- 利用dom4j解析xml--天气预报
- angular调用WCF服务,读取文件夹下图片显示列表,下载另存为图片
- CUDA进阶第二篇:巧用PTX
- 【学习总结】iOS 数据保存几种方式总结
- Unix/linux信号意义