題目鏈接: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);
}
}
}
}