uva572--dfs求八连块
来源:互联网 发布:office for mac破解 编辑:程序博客网 时间:2024/04/27 20:00
题意:
输入一个 m 行 n 列的字符矩阵,统计字符 @ 能组成多少八连块,如果两个字符 @ 所在的格子相邻(横竖或者对角线的方向),就
说他们组成了一个八连块,问图中一共有多少个八连块。
Sample Input:
1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5
****@
*@@*@
*@**@
@@@*@
@@**@
0 0
Sample Output:
0
1
2
2
分析:
图和二叉树一样,也有自己的dfs 和 bfs遍历,一般dfs用来求连通块问题,bfs用来找最短路问题,这个题目就是一个典型的dfs求八
连块的问题,可以从每个 @ 字符出发,递归遍历他周围八个方向的字符,看是否是 @ 格子,如果是就标记一下,证明该格子遍历
过,这样在以后的访问的时候,就能知道他是否被访问过,从而避免同一个格子被访问多次。下面的代码用一个二重循环来寻找八
连块,当然也可以用常量数组或者8条dfs遍历,在这里说一下,图的dfs遍历用递归实现,bfs遍历则是用队列(或者数组)实现,
类似的还有求二连块,四连块,等等,都可以用dfs遍历来实现,只需要改一下行走函数就可以。
下面上代码:
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;int n, m, maxz[105][105];char str[105][105];void dfs(int r,int c,int id){ if(r < 0 || r >= n ||c < 0 ||c >= m) return; if(maxz[r][c] > 0 || str[r][c] != '@') return; maxz[r][c] = id; for(int dr = -1; dr <= 1; dr++)///两个方向同时移动可以往八个方向移动 for(int dc = -1; dc <= 1; dc++)///而四连块则是单移动,仅一个for循环。 if(dr != 0 || dc != 0)///这儿同时体现八连块,八方向 dfs(r + dr, c + dc, id);}int main(){ while(scanf("%d%d",&n, &m) == 2&&n,m) { for(int i = 0; i < n; i++) cin >>str[i]; memset(maxz, 0, sizeof(maxz)); int cnt = 0; for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) { if(str[i][j] == '@'&&maxz[i][j] == 0) { dfs(i,j, ++cnt); cnt = max(0, cnt); } } cout <<cnt<<endl; }}
下面上四连块:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn=100+5;int maze[maxn][maxn];///顶点访问状态int R,C,K;///R行C列K个水块int cnt,ans;///cnt是计算访问的格子数///两个表示方向数组int dr[]= {-1,1,0,0}; //上,下,左,右int dc[]= {0,0,-1,1};void dfs(int r,int c) ///r是行坐标,c是列坐标{ if(r<1||r>R ||c<1||c>C || maze[r][c]==0) return ;///超出范围或已经访问过的格子 maze[r][c] = 0;///访问的格子 cnt++; for(int d=0; d<4; d++)///四连块 dfs(r+dr[d],c+dc[d]);}int main(){ while(scanf("%d%d%d",&R,&C,&K) == 3) { for(int i=1; i<=R; i++)///一定是从1开始 for(int j=1; j<=C; j++) maze[i][j] = 0;///将初始的maze数组全部设置成false while(K--)///输入有水的格子坐标,设置成true { int i,j; scanf("%d%d",&i,&j); maze[i][j] = 1; } ans=0; for(int i=1; i<=R; i++) for(int j=1; j<=C; j++) if(maze[i][j]==1) { cnt=0; dfs(i,j); ans=max(ans,cnt);///如果没有则输出0 } printf("%d\n",ans); } return 0;}
代码实现:#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;int map[650][650],p[650][650],x[650],y[650],vis[650];int n,num,t,k;char s[650][650];bool Search(int i)///其实就是一个dfs{ int j; for(j=0; j<num; j++) { if(map[i][j] && !vis[j]) { vis[j]=1; if(!y[j]||Search(y[j])) { y[j]=i; x[i]=j; return true; } } } return false;}int match(){ memset(x,0,sizeof(x)); memset(y,0,sizeof(y)); int ans=0; for(int i=0; i<num; i++)///寻找増广路 { memset(vis,0,sizeof(vis)); if(Search(i))///统计满足二连块的个数 ans++; } return ans/2;}int main(){ k=1; cin>>t; while(t--) { memset(map,0,sizeof(map)); cin>>n; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) cin>>s[i][j]; } for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(s[i][j]=='#') p[i][j]=num++; } } for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(s[i][j]=='#') { if(j<n-1 && s[i][j+1]=='#') { map[p[i][j]][p[i][j+1]]=1; map[p[i][j+1]][p[i][j]]=1; } if(j<n-1 && s[i+1][j]=='#') { map[p[i][j]][p[i+1][j]]=1; map[p[i+1][j]][p[i][j]]=1; } } } } int p=match(); printf("Case %d: %d\n",k++,p); } return 0;}
1 0
- uva572--dfs求八连块
- UVa572 Oil Deposits(DFS)
- UVA572 Oil Deposits dfs
- Uva572种子填充<dfs>
- uva572(DFS 油田)
- uva572--oil deposits--dfs算法
- uva572
- UVA572
- uva572
- UVA572
- uva572
- uva572
- uva572
- uva572
- UVa572
- uva572 Oil Deposits(启发DFS)
- UVA572 HDU1241 POJ1562 Oil Deposits【DFS】
- 例题6-12 UVa572 Oil Deposits(DFS)
- Apache Struts2任意代码执行漏洞(S2-032)检测程序
- Spring AOP的日志记录
- Android Studio 多渠道打包、自动版本号及 gradlew 命令的基本使用
- iOS中的动画
- Spring和MyBatis环境整合
- uva572--dfs求八连块
- 【技术宅拯救世界】在Windows Server2012上利用OpenVPN搭建自己的VPN服务器
- MAC使用Tip (terminal,adb,shell)
- 如何将word转换成excel表格格式
- android L 启动流程
- 大神教我们爬虫---神射手网站
- Fedora21下R语言包的下载安装
- AngularJs(三)作用域
- Android 研发的源码