【HDU - 1241】Oil Deposits (连通块问题 属于求大海中的岛屿个数 类似问题)

题干:

 

The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid. 

InputThe input file contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket. 
OutputFor each grid, output the number of distinct oil deposits. Two different pockets are part of the same oil deposit if they are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets. 
Sample Input

1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5 
****@
*@@*@
*@**@
@@@*@
@@**@
0 0 

Sample Output

0
1
2
2

 

解题报告:

 

    dfs水题,但是做题效率并不好。自己想想为什么。

错误代码:(是我想多了、、、)(想法是如果周围)

#include<bits/stdc++.h>using namespace std;char maze[105][105];
bool bk[105][105];
int main()
{int cnt=1;int n,m;while(cin>>m>>n) {memset(bk,0,sizeof(bk) ) ;memset(maze,0,sizeof(maze) ); if(m==0) break;cnt=0;for(int i = 1; i<=m; i++) scanf("%s",maze[i]+1);for(int i = 1; i<=m; i++) {for(int j = 1; j<=n; j++) {if(maze[i][j]=='*') continue;if(bk[i][j]==1) continue;if( !bk[i][j+1] && !bk[i+1][j+1] && !bk[i+1][j] && !bk[i+1][j-1] && !bk[i][j-1]&& !bk[i-1][j-1]&& !bk[i-1][j]&& !bk[i-1][j+1]){cnt++;if(maze[i][j+1]=='@') bk[i][j+1]=1;if(maze[i+1][j+1]=='@') bk[i+1][j+1]=1;if(maze[i+1][j]=='@') bk[i+1][j]=1;if(maze[i+1][j-1]=='@') bk[i+1][j-1]=1;if(maze[i][j-1]=='@') bk[i][j-1]=1;if(maze[i-1][j-1]=='@') bk[i-1][j-1]=1;if(maze[i-1][j]=='@') bk[i-1][j]=1;if(maze[i-1][j+1]=='@') bk[i-1][j+1]=1;}bk[i][j]=1;//别放到那个括号里面啊!!! }}printf("%d\n",cnt);}return 0 ;
}
	int cnt=1;int n,m;while(cin>>m>>n) {memset(bk,0,sizeof(bk) ) ;memset(maze,0,sizeof(maze) ); if(m==0) break;cnt=0;for(int i = 1; i<=m; i++) scanf("%s",maze[i]+1);for(int i = 1; i<=m; i++) {for(int j = 1; j<=n; j++) {if(maze[i][j]=='*') continue;if(bk[i][j]==1) continue;if( !bk[i][j+1] && !bk[i+1][j+1] && !bk[i+1][j] && !bk[i+1][j-1] && !bk[i][j-1]&& !bk[i-1][j-1]&& !bk[i-1][j]&& !bk[i-1][j+1]){cnt++;if(maze[i][j+1]=='@') bk[i][j+1]=1;if(maze[i+1][j+1]=='@') bk[i+1][j+1]=1;if(maze[i+1][j]=='@') bk[i+1][j]=1;if(maze[i+1][j-1]=='@') bk[i+1][j-1]=1;if(maze[i][j-1]=='@') bk[i][j-1]=1;if(maze[i-1][j-1]=='@') bk[i-1][j-1]=1;if(maze[i-1][j]=='@') bk[i-1][j]=1;if(maze[i-1][j+1]=='@') bk[i-1][j+1]=1;}bk[i][j]=1;//别放到那个括号里面啊!!! }}printf("%d\n",cnt);}return 0 ;
}

给一个样例:

***#

*#*#

**#*

就不立了。

 

ac代码:

#include<bits/stdc++.h>using namespace std;char maze[105][105];
bool bk[105][105];
int n,m;
void dfs(int x,int y) {//属于先深入再判断型 。一般写深搜都是for一个方向数组,然后先判断,再进入型。 这种题用前者会减少代码量毕竟没有for循环了得一个一个的if就很麻烦 if(maze[x][y]!='@' || x<1 || y<1 || x>m || y>n) return;      maze[x][y] = 'x';//这步很关键。  dfs(x-1, y-1);  dfs(x-1, y);  dfs(x-1, y+1);  dfs(x, y-1);  dfs(x, y+1);  dfs(x+1, y-1);  dfs(x+1, y);  dfs(x+1, y+1);  
}
int main()
{int cnt=1;while(cin>>m>>n) {memset(bk,0,sizeof(bk) ) ;memset(maze,0,sizeof(maze) ); if(m==0) break;cnt=0;for(int i = 1; i<=m; i++) scanf("%s",maze[i]+1);for(int i = 1; i<=m; i++) {for(int j = 1; j<=n; j++) {if(maze[i][j]!='@') continue;//不要写 maze[i][j]=='*'!!因为你这里面还有'x'出现啊 dfs(i,j); cnt++;}}printf("%d\n",cnt);}return 0 ;
}

 

总结:

 

    1.虽然是一道水题但是还是有很多问题需要注意的。可能是因为太长时间没写深搜了吧,有点小手生。

    2.本题的搜索属于先深入再判断型 。一般写深搜(尤其是地图问题)都是for一个方向数组,然后先判断,再进入型。 这种题用前者会减少代码量毕竟没有for循环了得一个一个的if就很麻烦 。

    3.不要想当然的用for循环!那样是肯定有陷阱的!由给出的那个样例你也可以发现用for遍历和dfs深搜的最主要区别就是dfs可以跳跃的选择我们想要的部分,而不是只能老老实实的挨个遍历。dfs牺牲了空间(递归层数深了还有可能栈溢出)和效率(此题并没有体现出来,因为相当于剪枝十分优雅)的同时也是有自己的优势所在的!

    4.连通块问题可否通用?一个点很实用,那就是改原地图,比如此题中走过的'@'就改为别的字符,这样避免了开一个新的vis数组了!(或者用着色问题也可以解)

5.连通块问题也可以用并查集来做!贴一个代码:

    给定一个由1和0组成的二维字符数组,1代表陆地,0代表水。问被水包围的连通陆地区域的个数。

class Solution {
public:vector<int> pre;int count=0;int numIslands(vector<vector<char>>& grid) {if(grid.size()==0 || grid[0].size()==0)return 0;int row = grid.size();int col = grid[0].size();pre.resize(row*col+1,0);//对pre数组进行初始化for(int i=0;i<row;i++)for(int j=0;j<col;j++){int num = col*i+j;pre[num] = num;}//遍历图中的每个点for(int i=0;i<row;i++)for(int j=0;j<col;j++){if(grid[i][j]=='1'){int down=i+1,right=j+1;if(down<row && grid[down][j]=='1')join(col*i+j,col*down+j);if(right<col && grid[i][right]=='1')join(col*i+j,col*i+right);}}//再遍历一次,计算islands的个数int ans = 0;for(int i=0;i<row;i++)for(int j=0;j<col;j++){int num = col*i+j;if(pre[num] == num && grid[i][j]=='1')ans++;}return ans;}//并,将联通的点的pre设为同一个值void join(int x,int y){int fx=find(x);int fy=find(y);if(fx != fy)pre[fx] = fy;}//找到a的祖先,并且路径压缩int find(int a){if(pre[a] != a)pre[a] = find(pre[a]);return pre[a];}
};

 

贴一道类似题目 :

 

    蓝桥杯山东省赛习题9 全球变暖https://blog.csdn.net/qq_41289920/article/details/81056373

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/442113.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

asp.net core mvc接口,请求响应统一日志管理

如何为api所有的请求和响应做一个统一的日志记录 1.创建日志类 public class RequestResponseLog {public string Url { get; set; }public IDictionary<string, string> Headers { get; set; } new Dictionary<string, string>();public string Method { get; …

Windows下 Python3.7.0 运行环境的搭建 一套操作后就可以使用Python写代码啦~

1.下载Python for windows 废话不说&#xff0c;直接上网址&#xff1a;https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe 2.安装Python for windows 运行安装文件之后&#xff0c;你会看到这个页面&#xff1a;不得不说Python 在 Windows平台下的安装比傻瓜式还傻瓜…

【HDU - 1873】 看病要排队(优先队列)

题干&#xff1a;看病要排队这个是地球人都知道的常识。 不过经过细心的0068的观察&#xff0c;他发现了医院里排队还是有讲究的。0068所去的医院有三个医生&#xff08;汗&#xff0c;这么少&#xff09;同时看病。而看病的人病情有轻重&#xff0c;所以不能根据简单的先来先服…

h5 网站滚动到某个位置

var height $("#0107").offset().top&#xff1b; //获得要滚动到的高度 $("html:not(:animated),body:not(:animated)").animate({ scrollTop: 392 }, slow); //滚动

【HDU - 1856】 More is better(并查集)(还需要空间优化。。)

题干&#xff1a;Mr Wang wants some boys to help him with a project. Because the project is rather complex, the more boys come, the better it will be. Of course there are certain requirements. Mr Wang selected a room big enough to hold the boys. The boy who…

.Net开发WebApi如何使用JObject对象接收参数

1.需要引入包Microsoft.AspNetCore.Mvc.NewtonsoftJson 2.在StartUp.cs的ConfigureServices方法中进行注册 services.AddControllers().AddNewtonsoftJson(options >{options.SerializerSettings.ContractResolver new DefaultContractResolver();}); 3.前端ajax使用 $.aja…

【HDU - 1326】Box of Bricks(模拟水题)

题干&#xff1a;Little Bob likes playing with his box of bricks. He puts the bricks one upon another and builds stacks of different height. Look, Ive built a wall!, he tells his older sister Alice. Nah, you should make all stacks the same height. Then you …

微信公众平台网站开发JS_SDK遇到的bug——wx.config注册提示成功,但部分接口注册失败问题

1 2022-02-23 使用微信公众平台调用扫一扫接口&#xff0c;总是注册不成功 这是进行注册后成功注册的接口提示 尝试注册了以下接口 拥有相关权限 解决办法&#xff1a;猜测失败原因为&#xff1a;子界面进行注册&#xff0c;在父界面进行注册后&#xff0c;成功

layui 流加载flow遇到的问题

目的&#xff1a;在界面中想实现&#xff0c;进入界面加载部分数据&#xff0c;拥有搜索功能&#xff0c;可加载新的数据以替换旧数据&#xff0c;替换过程中想要清空现有数据时&#xff0c;使用jquery方法 $(*).remove();删除了流控件&#xff0c;特别记录一下问题&#xff0…

【HDU - 1276】士兵队列训练问题 (报数问题 模拟)

题干&#xff1a;某部队进行新兵队列训练&#xff0c;将新兵从一开始按顺序依次编号&#xff0c;并排成一行横队&#xff0c;训练的规则如下&#xff1a;从头开始一至二报数&#xff0c;凡报到二的出列&#xff0c;剩下的向小序号方向靠拢&#xff0c;再从头开始进行一至三报数…

React学习,Babel ES6兼容运行使用的命令行整理

测试项目为&#xff0c;一个js文件引用其他ES6编写的文件&#xff0c;最终网页中引用打包好的最终js文件 注意&#xff1a;需要安装Node.js,没有的话&#xff0c;需要搜索安装 1 Browserify //在终端中输入如下命令&#xff0c;可以通过 npm 安装 Browserify&#xff1a; $ n…

【HDU - 1870】愚人节的礼物(水题模拟 思想类似于栈?)

题干&#xff1a;四月一日快到了&#xff0c;Vayko想了个愚人的好办法——送礼物。嘿嘿&#xff0c;不要想的太好&#xff0c;这礼物可没那么简单&#xff0c;Vayko为了愚人&#xff0c;准备了一堆盒子&#xff0c;其中有一个盒子里面装了礼物。盒子里面可以再放零个或者多个盒…

c++经典编程题_【经典C语言知识】C/C++编程难点总结

知识点一&#xff1a;指针1. 指针&#xff1a;变量在内存中所存储空间的首编号&#xff0c;就称作为该变量的地址&#xff0c;也叫做指针。指针变量: 他专门存放另外一个变量的指针 int* p_age&#xff1b;p_age&age;2.数组与指针使用指针访问一维数组元素&#xf…

asp.net mvc 缓存CaChe使用

缓存存储帮助类 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Caching;public class TCatche{/// <summary> /// 获取数据缓存 /// </summary> /// <param name"cacheKey">键<…

【CF#459 A 】Pashmak and Garden (水题)

题干:Pashmak has fallen in love with an attractive girl called Parmida since one year ago... Today, Pashmak set up a meeting with his partner in a romantic garden. Unfortunately, Pashmak has forgotten where the garden is. But he remembers that the garden l…

c++ 低位在前 高位在后_A股市场:如果股票涨停后第二天“高开低走”,你知道怎么操作才能利益最大化吗?...

(本文由公众号越声策略(yslc188)整理&#xff0c;仅供参考&#xff0c;不构成操作建议。如自行操作&#xff0c;注意仓位控制和风险自负。)如果你的股票涨停后第二天高开低走&#xff0c; 后市怎么操作&#xff1f;简单来讲&#xff0c;高开低走就是开盘价高于上个交易日的收盘…

2018年工业机器人销量排位_工业机器人年销量连续七年居世界首位 专家建议开辟新市场...

12月17日&#xff0c;粤港澳大湾区人工智能与机器人大会在广东四会举行。本次大会的主题是“智慧湾区&#xff0c;引领未来”。大会邀请了国际机器人联合会、粤港澳大湾区相关专家、国内外学者和企业专家深度交流&#xff0c;共话机器人发展的新风向。中国机械工业联合会执行副…

*【HDU - 2473】Junk-Mail Filter (并查集--删点操作)

题干&#xff1a; Recognizing junk mails is a tough task. The method used here consists of two steps: 1) Extract the common characteristics from the incoming email. 2) Use a filter matching the set of common characteristics extracted to determine whether…

文件内容查找方式

第一种&#xff0c;使用windows自带的查找工具 搜索工具里面有”高级选项“&#xff0c;选择”文件内容“然后进行搜索即可 第二种&#xff0c;使用命令行 在需要进行搜索的文件夹下使用命令行&#xff1a; Get-ChildItem -Path F:\ -Recurse | Select-String -Pattern &qu…

【HDU - 1863】 畅通工程(并查集+最小生成树)

题干&#xff1a; 省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通&#xff08;但不一定有直接的公路相连&#xff0c;只要能间接通过公路可达即可&#xff09;。经过调查评估&#xff0c;得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编…