题目类型: 搜索
样例输入:
1 1 * 3 5 *@*@* **@** *@*@* 1 8 @@****@* 5 5 ****@ *@@*@ *@**@ @@@*@ @@**@ 0 0
样例输出:
0 1 2 2
分析:
这一题可以说是搜索中最基础的一题之一。 要找出相连在一起的有多少块, 因此, 依次枚举,遇到@时就进行搜索,用深搜,广搜都行,目的是把相连的@都标记为已访问。
下面给出用DFS(深搜)和BFS(广搜)的代码
DFS 1 :递推
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
int m,n,idx[105][105];
char pic[105][105];
void dfs(int r,int c,int id)
{
if (r<0 || r>=m || c<0 || c>= n) return ;
if(idx[r][c] >0 || pic[r][c] != '@') return ;
idx[r][c] = id;
for (int dr = -1;dr <= 1;dr++)
{
for (int dc = -1;dc <= 1;dc++)
{
if(dr != 0 || dc != 0)
dfs(r+dr,c+dc,id);
}
}
}
int main()
{
int i,j,cnt;
while (cin>>m>>n,m&&n)
{
for (i=0;i<m;i++)
{
cin>>pic[i];
}
cnt = 0;
memset(idx,0,sizeof(idx));
for (i=0;i<m;i++)
{
for (j=0;j<n;j++)
{
if(idx[i][j]==0 && pic[i][j] == '@')
dfs(i,j,++cnt);
}
}
cout<<cnt<<endl;
}
return 0;
}
这种方法当数据量很大时,可能会有栈溢出
DFS 2:栈
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <stack>
using namespace std;
int m,n,idx[105][105];
char pic[105][105];
struct Node {int x;int y;};
stack<Node> st;
void dfs(int r,int c)
{
// if (r<0 || r>=m || c<0 || c>= n) return ;
// if(idx[r][c] >0 || pic[r][c] != '@') return ;
while(!st.empty()) st.pop();
Node temp;
temp.x = r;
temp.y = c;
st.push(temp);
idx[r][c] = 1;
while (!st.empty())
{
temp = st.top();
st.pop();
for (int dr = -1;dr <= 1;dr++)
{
for (int dc = -1;dc <= 1;dc++)
{
int drr = dr+temp.x;
int dcc = dc+temp.y;
if((dr != 0 || dc != 0) && drr>=0 && drr<m && dcc>=0 && dcc<n && pic[drr][dcc] == '@' && !idx[drr][dcc])
// dfs(r+dr,c+dc,id);
{
Node t;
idx[drr][dcc] =1;
t.x = drr;
t.y = dcc;
st.push(t);
}
}
}
}
}
int main()
{
int i,j,cnt;
while (cin>>m>>n,m&&n)
{
for (i=0;i<m;i++)
{
cin>>pic[i];
}
cnt = 0;
memset(idx,0,sizeof(idx));
for (i=0;i<m;i++)
{
for (j=0;j<n;j++)
{
if(idx[i][j]==0 && pic[i][j] == '@')
{
cnt++;
dfs(i,j);
}
}
}
cout<<cnt<<endl;
}
return 0;
}
BFS:(队列实现)可用STL 也可以数组
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <stack>
#include <queue>
using namespace std;
int m,n,idx[105][105];
char pic[105][105];
struct Node {int x;int y;};
//stack<Node> st;
//queue<Node> st;
Node que[105];
void dfs(int r,int c)
{
// if (r<0 || r>=m || c<0 || c>= n) return ;
// if(idx[r][c] >0 || pic[r][c] != '@') return ;
//while(!st.empty()) st.pop();
que[0].x = r;
que[0].y = c;
idx[r][c] = 1;
int front=0;
int rear=1;
while (front < rear)
{
Node temp=que[front++];
for (int dr = -1;dr <= 1;dr++)
{
for (int dc = -1;dc <= 1;dc++)
{
int drr = dr+temp.x;
int dcc = dc+temp.y;
if((dr != 0 || dc != 0) && drr>=0 && drr<m && dcc>=0 && dcc<n && pic[drr][dcc] == '@' && !idx[drr][dcc])
{
idx[drr][dcc] =1;
que[rear].x = drr;
que[rear].y = dcc;
rear++;
}
}
}
}
}
int main()
{
int i,j,cnt;
while (cin>>m>>n,m&&n)
{
for (i=0;i<m;i++)
{
cin>>pic[i];
}
cnt = 0;
memset(idx,0,sizeof(idx));
for (i=0;i<m;i++)
{
for (j=0;j<n;j++)
{
if(idx[i][j]==0 && pic[i][j] == '@')
{
cnt++;
dfs(i,j);
}
}
}
cout<<cnt<<endl;
}
return 0;
}
#include <stdio.h>
#include <string.h>
char map[105][105],mat[105][105];
int vis[105][105];
void dfs(int i,int j)
{
if(vis[i][j] || mat[i][j] == '*')
return ;
vis[i][j] = 1;
dfs(i-1,j-1);
dfs(i-1,j);
dfs(i-1,j+1);
dfs(i,j-1);
dfs(i,j+1);
dfs(i+1,j-1);
dfs(i+1,j);
dfs(i+1,j+1);
}
int main()
{
int n,m;
while(~scanf("%d%d%*c",&n,&m))
{
memset(map,0,sizeof(map));
memset(mat,'*',sizeof(mat));
memset(vis,0,sizeof(vis));
int i,j,cnt = 0;
if(!m&&!n)
break;
for(i = 0;i<n;i++)
{
for(j = 0;j<m;j++)
{
scanf("%c",&map[i][j]);
mat[i+1][j+1] = map[i][j];
}
getchar();
}
for(i = 1 ;i<=n;i++)
{
for(j = 1;j<=m;j++)
{
if(!vis[i][j] && mat[i][j] == '@')
{
dfs(i,j);
cnt++;
}
}
}
printf("%d\n",cnt);
}
return 0;
}