题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1241
题目大意:
有一个地区,用网格分成一个一个小方格,有的方格会有油田。有油田的地区用 '@' 表示,没有的地区用 '*' 表示。当一块油田的相邻八个位置中有油田时,这些相邻的油田看做一个油田。输入这个地区的油田分布,输出这个地区一共有多少油田。
解题思路:
这道题是最简单的搜索题,使用深搜广搜都可以。最开始做这道题时,当时刚学会搜索,在高数课上用C4droid写出来了(后来高数喜闻乐见的挂了......)。写搜索时有几个需要注意的地方,第一是对搜索中已访问节点的标记,避免重复搜索导致死循环;第二是注意多维数组的下标与坐标的区别,二维数组中第一个下标代表行(也就是坐标中的y),第二个下标代表列(也就是坐标中的x);还有就是输入中的字符 '\n' 的处理,容易导致输入的错误。
代码:
dfs:
/*
ID: Code-Cola
PROG: 1241
LANG: C++
*/
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
/********** 全局变量 **********/
int dir[8][2] = {-1,-1,0,-1,1,-1,-1,0,1,0,-1,1,0,1,1,1}; //方向数组
struct node //节点结构体
{
int x,y;
};
string s[110];
int n,m;
/********** 函数声明 **********/
bool IsOk(int x, int y); //判断是否访问越界
void dfs(int x, int y); //深搜
int main()
{
int i,j,sum;
while (cin >> m >> n && m && n) {
getchar(); //'\n'
for (i = 0; i < m; i++)
getline(cin,s[i]);
for (i = 0, sum = 0; i < m; i++)
for (j = 0; j < n; j++)
if (s[i][j] == '@') {
dfs(j,i);
sum++; //记录油田数目
}
cout << sum << endl;
}
return 0;
}
bool IsOk(int x,int y)
{
return x >= 0 && x < n ? y >= 0 && y < m ? true : false : false;
}
void dfs(int x, int y)
{
node t;
s[y][x] = '*'; //标记
for (int i = 0; i < 8; i++){
t.x = x + dir[i][0];
t.y = y + dir[i][1];
if (IsOk(t.x, t.y) && s[t.y][t.x] == '@') //判断是否满足搜索条件
dfs(t.x, t.y);
}
}
bfs:
/*
ID: Code-Cola
PROG: 1241
LANG: C++
*/
#include<iostream>
#include<cstdio>
#include<string>
#include<queue>
using namespace std;
/********** 全局变量 **********/
int dir[8][2] = {-1,-1,0,-1,1,-1,-1,0,1,0,-1,1,0,1,1,1}; //方向数组
struct node //节点结构体
{
int x,y;
};
string s[110];
int n,m;
queue<node> q;
/********** 函数声明 **********/
bool IsOk(int x, int y); //判断是否访问越界
void bfs(int x, int y); //广搜
int main()
{
int i,j,sum;
while (cin >> m >> n && m && n) {
getchar(); //'\n'
for (i = 0; i < m; i++)
getline(cin,s[i]);
for (i = 0, sum = 0; i < m; i++)
for (j = 0; j < n; j++)
if (s[i][j] == '@') {
bfs(j,i);
sum++; //记录油田数目
}
cout << sum << endl;
}
return 0;
}
bool IsOk(int x,int y)
{
return x >= 0 && x < n ? y >= 0 && y < m ? true : false : false;
}
void bfs(int x, int y)
{
node t,temp;
while (!q.empty()) { //清空队列 PS:貌似没必要
q.pop();
}
t.x = x, t.y = y;
q.push(t);
s[y][x] = '*';
while (!q.empty()) {
t.x = q.front().x;
t.y = q.front().y;
q.pop();
for (int i = 0; i < 8; i++) { //8个方向搜索
temp.x = t.x + dir[i][0];
temp.y = t.y + dir[i][1];
if (IsOk(temp.x, temp.y) && s[temp.y][temp.x] == '@') {
s[temp.y][temp.x] = '*'; //一定要进入队列前标记不可走
q.push(temp);
}
}
}
}