uva 657 The die in cast (掷骰子) —— DFS
2016-05-20 12:03
411 查看
/** 序号:num_3 作者:MrZhang 日期:2016-5-20 题目名称: The die in cast(掷骰子) 题目来源: uva —— 657 —— The die is cast 网址: 英文题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19322 中文翻译:http://www.cnblogs.com/scau20110726/archive/2012/11/11/2764626.html 数据样例: 30 15 .............................. .............................. ...............*.............. ...*****......****............ ...*X***.....**X***........... ...*****....***X**............ ...***X*.....****............. ...*****.......*.............. .............................. ........***........******..... .......**X****.....*X**X*..... ......*******......******..... .....****X**.......*X**X*..... ........***........******..... .............................. 0 0 输出: Throw 1 1 2 2 4 */ #include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <algorithm> #define maxn 60 using namespace std; char G[maxn][maxn]; int visitedI[maxn][maxn]; //!遍历 以'.'为背景的整个区域, 找区域I 时 使用 int visitedII[maxn][maxn]; //!在 以'.'为背景的整个区域中, 找区域II 时 使用。 int h,w; //!以'.'为背景的整个区域 共有 h行,w列 int numi; //!区域I中区域II的个数,每进入一个新的区域I时将numi清零。 vector<int> num; //!以'.'为背景的整个区域中有多个区域I,每个区域I中有多个区域II,num一次存储每个区域I中区域II的个数。 bool checkI(int x,int y){ //!用DFSI()遍历以'.'为背景的整个区域,找区域I时使用此函数检查。 if(x >= 0 &&x <= h-1 && y >= 0 && y <= w-1){ //!是否越界 if((G[x][y] == '*' || G[x][y] == 'X') && !visitedI[x][y]){ return true; } } return false; } bool checkII(int x,int y){//!用DFSII()遍历某个区域I,找区域II时使用此函数检查。 if(x >= 0 &&x <= h-1 && y >= 0 && y <= w-1){ if(G[x][y] == 'X' && !visitedII[x][y]){ return true; } } return false; } //! 上下 左右 int dx[6]={-1,1, 0,0}; int dy[6]={ 0,0,-1,1}; void DFSII(int x,int y){ //!在某个区域I中找区域II for(int i=0;i<4;i++){ int u = x + dx[i],v = y + dy[i]; if(checkII(u,v)){ visitedII[u][v] = 1; DFSII(u,v); } } } /** 使用双重DFS()遍历该区域,找区域I中区域II的个数。 */ void DFSI(int x,int y){//!在 以'.'为背景的整个区域 中找区域I for(int i=0;i<4;i++){ int u = x + dx[i],v = y + dy[i]; if(checkI(u,v)){ visitedI[u][v] = 1; if(checkII(u,v)){//!在遍历当前区域I时,找到了一个新的区域II visitedII[u][v] = 1; numi ++; //!将计数加1 DFSII(u,v);//!遍历这个新区域II } DFSI(u,v);//!继续遍历该区域I } } } int main(){ int orderNum = 1; while(scanf("%d%d",&w,&h) == 2){//!h行,w列 if(!w && !h) break; memset(G,'.',sizeof(G)); memset(visitedI,0,sizeof(visitedI)); memset(visitedII,0,sizeof(visitedII)); num.clear(); for(int i=0;i<h;i++){ for(int j=0;j<w;j++){ cin>>G[i][j]; } } for(int i=0;i<h;i++){ for(int j=0;j<w;j++){ if(G[i][j] == '*' && !visitedI[i][j]){ //!说明找到了一个新的区域I visitedI[i][j] = 1; numi = 0;//!初始化区域II的个数 DFSI(i,j);//!遍历这个新的区域I,并在此函数中计算 该区域I中的 区域II 的个数 num.push_back(numi); //!记录下 新找到的区域I 中的区域II的个数 } } } cout<<"Throw "<<orderNum ++<<endl; sort(num.begin(),num.end()); for(int i=0;i<num.size();i++){ if(!i) cout<<num[i]; else cout<<" "<<num[i]; } cout<<endl<<endl; } return 0; } /** 总结: 题型: 大标题:图的遍历 小标题:计算“图1中的图2” 原理:深度优先搜索(DFS) 技巧:使用双重DFS(),将DFS()嵌套使用。 用一层DFSI()找图1,用二层DFSII()找图2。 */
相关文章推荐
- dubbo.xsd下载文件路径
- 如何在QT中显示中文字符
- linux awk命令详解
- jenkins 安装配置: centos-master windows/linux-slave + nginx代理 + node + job
- 源码解析ConcurrentHashMap
- NOIP2007题解
- Linux之常用命令
- bzoj 1911 [Apio2010]特别行动队
- MSSQL 局部变量与全局变量
- zoj 2236 Wireless Network
- Android显示一张很长的图
- 遇见你,用尽了我一生的幸运
- 添加自定义的tabBar
- LeetCode OJ 66. Plus One
- SQL SERVER 2012 只能识别20个CPU的问题
- Yii框架表单模型和验证用法
- HQL数据查询基础(三)
- 本周任务
- 小松api文档系统终于完成
- 从另外角度-解决ASP.NET每一个页面首次访问慢的问题