【题解】Reach-Top 1115 勘探油田

题目描述

某石油勘探公司正在按计划勘探地下油田资源,工作在一片长方形的地域中。他们首先将该地域划分为许多小正方形区域,然后使用探测设备分别探测每一块小正方形区域内是否有油。若在一块小正方形区域中探测到有油,则标记为’\(@\)’,否则标记为’\(*\)’。如果两个相邻区域都为\(1\),那么它们同属于一个石油带,一个石油带可能包含很多小正方形区域,而你的任务是要确定在一片长方形地域中有多少个石油带。 所谓相邻,是指两个小正方形区域上下、左右、左上右下或左下右上同为’\(@\)’。

输入

输入数据将包含一些长方形地域数据,每个地域数据的第一行有两个正整数\(m\)和\(n\),表示该地域由\(m×n\)个小正方形所组成,如果\(m\)为\(0\),表示所有输入到此结束;否则,后面\(m\)(\(1≤m≤100\))行数据,每行有\(n\)(\(1≤n≤100\))个字符,每个字符为’\(@\)’或’\(*\)’,表示有油或无油。每个长方形地域中,’\(@\)’的个数不会超过\(100\)。

输出

每个长方形地域,输出油带的个数,每个油带值占独立的一行。油带值不会超过100。

样例输入

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

样例输出

0
1
2
2

思路&解答

经典的连通块题目,使用DFS搜索。
题意让我们求油田的块数,也就是求联通块数。
首先先要清楚搜索方向,我们将当前格定义为\((x,y)\),则以此格可推出其他八格分别为:

\((x+1,y),(x-1,y),(x,y+1),(x,y-1),(x+1,y+1),(x-1,y-1),(x+1,y-1),(x-1,y+1)\)。
如下图:

故我们的方向函数gox[],goy[]为:

const int gox[] = { 1,-1,0,0,1,-1,1,-1 };
const int goy[] = { 0,0,1,-1,1,-1,-1,1 };

扫描全局见到‘\(@\)‘时调用DFS(int x,int y)函数,并且计数器sum自增\(1\)。
我们把每次走到的一格都标记为‘\(*\)‘,把油田覆盖为平地,以免重复计数。
再次覆盖一整块油田,如此反复直到所有的地均为‘\(*\)‘时结束。
完整的DFS(int x,int y)函数为:

void DFS(int x, int y)
{
    mp[x][y] = '*'; //mp[][]是存放地图的二维数组哦~~
    for (int i = 0; i < 8; i++)
    {
        int next_x = x + gox[i];
        int next_y = y + goy[i];
        if (next_x > 0 && next_y > 0 && next_x <= m && next_y <= n && mp[next_x][next_y] == '@')
            DFS(next_x, next_y); //下一步扫描
    }
}

最后,输出计数器的sum即可。

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 105;
const int gox[] = { 1,-1,0,0,1,-1,1,-1 };
const int goy[] = { 0,0,1,-1,1,-1,-1,1 };
char mp[maxn][maxn];
int m, n;
void DFS(int x, int y)
{
    mp[x][y] = '*';
    for (int i = 0; i < 8; i++)
    {
        int next_x = x + gox[i];
        int next_y = y + goy[i];
        if (next_x > 0 && next_y > 0 && next_x <= m && next_y <= n && mp[next_x][next_y] == '@')
            DFS(next_x, next_y);
    }
}
int main()
{
    while (cin >> m >> n && m)
    {
        int sum = 0;
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= n; j++)
                cin >> mp[i][j];
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= n; j++)
                if (mp[i][j] == '@')
                {
                    DFS(i, j);
                    sum++;
                }
        cout << sum << endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/binjiazhisheng/p/11370207.html

时间: 2024-11-08 21:53:16

【题解】Reach-Top 1115 勘探油田的相关文章

勘探油田

<pre name="code" class="cpp">#include <iostream> #include <cstring> using namespace std; char a[100][100]; int b[100][100],n,m; int x[]={0,-1,-1,-1,0,1,1,1}; int y[]={1,1,0,-1,-1,-1,0,1}; void dfs(int i,int j)//深度搜索 {

带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载

转载请注明出处:http://blog.csdn.net/lowprofile_coding/article/details/51321896 一 .前言 最近实在太忙,一个多礼拜没有更新文章了,于是今晚加班加点把demo写出来,现在都12点了才开始写文章. 1.我们的目标 把RecyclerView下拉刷新上拉加载更多加入到我们的开发者头条APP中. 2.效果图 3.实现步骤 找一个带上拉刷新下载加载更多的RecyclerView开源库,我们要站在巨人的肩膀上 下载下来自己先运行下demo,然

正则表达式部分特征实现设计实验

正则表达式 http://www.regexlab.com/zh/regref.htm 正则表达式(regular expression)就是用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征.比如 表达式“ab+” 描述的特征是“一个 'a' 和 任意个 'b' ”,那么 'ab', 'abb', 'abbbbbbbbbb' 都符合这个特征. 正则表达式可以用来:(1)验证字符串是否符合指定特征,比如验证是否是合法的邮件地址.(2)用来查找字符串,从一个长的文本中查找符

有限状态机与应用

有线状态机 http://www.ibm.com/developerworks/cn/linux/l-fsmachine/index.html 有限状态机是一种用来进行对象行为建模的工具,其作用主要是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件.在面向对象的软件系统中,一个对象无论多么简单或者多么复杂,都必然会经历一个从开始创建到最终消亡的完整过程,这通常被称为对象的生命周期. http://kb.cnblogs.com/page/528972/ 有限状态机的工作原理

跃居AppStore榜首的游戏&lt;别踩到白块儿&gt;源代码分析和下载(第一篇)----它怎么也能爆红?

AppStore和Android市场情况 莫名其妙爆红的游戏 真的莫名其妙,笔者下这个游戏两次,第一次在豌豆荚排行榜看到这款游戏,名字怪怪的,下载下来尝试一下,没觉得有什么新颖的,还在思虑这是不是刷榜刷上去的,果断卸载了:周末的时候逛逛app store,突然看到排行榜首位是Dont Tap The White Tile(后更名panio tiles ),翻译一下不就是别踩到白块儿,笔者震惊了,太莫名其妙了,这东西是真的火,不是刷榜刷出来的!游戏玩家们心理真的难以捉摸,又捧红了一款游戏: 近期爆

HiShader

HiShader.material vertex_program MyVertexShader glsl { source HiShader.vsh default_params { param_named_auto MVP worldviewproj_matrix } } fragment_program MyFragmentShader glsl { source HiShader.fsh default_params { param_named_auto Resolution viewpo

Android源代码学习笔记:android-Ultra-Pull-To-Refresh-master

学习要点:下拉刷新 这个小应用包含了在使用到GridView,FrameLayout,TextView,ListView等等控件时的所有下拉刷新效果下拉刷新具有极为强大的使用空间,几乎所有的应用都会用到. 源码解析文档:http://a.codekk.com/detail/Android/Grumoon/android-Ultra-Pull-To-Refresh%20%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90 public interface PtrHandler

HiCharacter

SinbadCharacterController.h /*************************************************** ©2014 Pf_D. All rights reserved. ***************************************************/ #pragma once #include "OGRE\Ogre.h" #include "OIS\OIS.h" using names

HiCelShading

Media cel_shading_diffuse.png,cel_shading_edge.png,cel_shading_specular.png, HiCelShading.material,HiCelShading.cg,ogrehead.mesh HiCelShading.material // ------------------------------- // Cel Shading Section // ------------------------------- vertex